¿Cuál es el segundo personaje que no se repite?


18

Basado en esta pregunta de la revisión de código

Dada una cadena no vacía de caracteres ASCII imprimibles, genera el segundo carácter no repetido. Por ejemplo, para entrada DEFD, salida F.

Entrada

Salida

  • El segundo carácter que no se repite, cuando se lee de izquierda a derecha, nuevamente en un formato adecuado.
  • El carácter de salida no distingue entre mayúsculas y minúsculas.
  • Si no existe dicho carácter (por ejemplo, todos los caracteres se repiten), envíe una cadena vacía.

Reglas

  • El algoritmo debe ignorar el caso. Es decir, Dy dcontar como el mismo personaje.
  • Un programa completo o una función son aceptables.
  • La cadena de entrada se garantizará no vacía (es decir, al menos un carácter de longitud).
  • La cadena de entrada es ASCII. Cualquier carácter válido podría repetirse, no solo alfanumérico (esto incluye espacios).
  • Las lagunas estándar están prohibidas.
  • Este es el por lo que se aplican todas las reglas habituales de golf, y gana el código más corto (en bytes).

Ejemplos

La entrada está en la primera línea, la salida está en la segunda línea.

DEFD
F

FEED
D

This is an example input sentence.
x

...,,,..,,!@
@

ABCDefgHijklMNOPqrsTuVWxyz
B

AAAAAABBBBB


Thisxthis


This this.
.

8
Si no fuera sensible a mayúsculas y minúsculas, consideraría hacerlo en Forth. Sin embargo, las operaciones de cadena apestan en ese idioma.
mbomb007

¿Qué pasa si mi idioma no admite letras minúsculas?
Adám

@ Adám ¿Utiliza una página de códigos diferente? ¿Cómo ingresaría normalmente una cadena ASCII si no admite letras minúsculas?
AdmBorkBork

1
El sistema que tenía en mente tenía una página de códigos de 7 bits; una página de códigos estándar modificada donde las letras mayúsculas ocupan las posiciones en minúsculas, y las posiciones en mayúsculas se utilizaron para los glifos. Esto se hizo en sistemas APL antiguos para que uno pudiera usar Shift para acceder a los glifos APL, mientras que las letras no desplazadas eran mayúsculas clásicas de estilo de codificación.
Adám

Respuestas:


10

MATL , 11 bytes

tk&=s1=)FT)

Esto sale con un error (permitido por defecto) si no hay un segundo carácter no repetido.

Pruébalo en línea!

Explicación

t      % Implicitly take input string. Duplicate
k      % Convert to lowercase
&=     % 2D array of equality comparisons
s      % Sum of each column
1=     % True for entries that equal 1
)      % Apply logical index to the input string to keep non-repeated characters
TF)    % Apply logical index to take 2nd element if it exists. Implicitly display 

La edición ninja ataca de nuevo. : P
Dennis

@Dennis Jajaja. Bueno, supongo que pronto eliminarás un par de bytes
Luis Mendo

10

Retina , 25 bytes

i!2=`(.)(?<!\1.+)(?!.*\1)

Pruébalo en línea! (La primera línea permite ejecutar el código en un conjunto de pruebas de varias entradas).

Explicación

Esta es solo una coincidencia de expresiones regulares, siendo la expresión regular:

(.)(?<!\1.+)(?!.*\1)

Es decir, haga coincidir un carácter y asegúrese de que no aparezca en ningún otro lugar de la entrada. El resto es configuración:

  • i activa la insensibilidad a mayúsculas y minúsculas.
  • ! le dice a Retina que imprima los partidos en lugar de contarlos.
  • 2= le dice a Retina que imprima solo el segundo partido en lugar de todos.

1
Ah, gracias por enseñarme sobre el 2=.
Leaky Nun

6

05AB1E, 15 12 bytes

l©v®y¢iy}}1@

Explicado

l©            # store lower case string in register
  v     }     # for each char in lower case string
   ®y¢iy      # if it occurs once in string, push it to stack
         }    # end if
          1@  # push the 2nd element from stack and implicitly display

Pruébalo en línea

Guardado 3 bytes gracias a @Adnan


O para 12 bytes l©v®y¢iy}}1@:).
Adnan

@Adnan: ¡Qué bien! No pensé en usar @.
Emigna

5

Python 2, 59 58 bytes

Devuelve una lista de un solo carácter, o una lista vacía si no hay salida. (Estúpida insensibilidad a las mayúsculas y minúsculas ...)

s=input().lower();print[c for c in s if s.count(c)<2][1:2]

Pruébalo en línea



No es una entrada válida. El usuario nunca debería tener que escapar de su entrada.
mbomb007 01 de

44
Claro que lo es. Proporcionamos listas en STDIN en el formato de lista de idiomas. ¿Por qué las cuerdas serían diferentes?
Dennis

5

Jalea , 11 bytes

Œlµḟœ-Q$Ḋḣ1

Pruébalo en línea! o verificar todos los casos de prueba .

Cómo funciona

Œlµḟœ-Q$Ḋḣ1  Main link. Argument: s (string)

Œl           Convert s to lowercase.
  µ          Begin a new, monadic chain. Argument: s (lowercase string)
       $     Combine the two links to the left into a monadic chain.
      Q        Unique; yield the first occurrence of each character.
    œ-         Perform multiset subtraction, removing the last occurrence of each
               character.
   ḟ         Filterfalse; keep characters that do not appear in the difference.
        Ḋ    Dequeue; remove the first character.
         ḣ1  Head 1; remove everything but the first character.

4

Lote, 171 bytes

@echo off
set a=.
set s=%~1
:l
if "%s%"=="" exit/b
set c=%s:~0,1%
call set t=%%s:%c%=%%
if "%s:~1%"=="%t%" set a=%a%%c%
set s=%t%
if "%a:~2%"=="" goto l
echo %c%

Formulación alternativa, también 171 bytes:

@echo off
set a=.
set s=%~1
:l
if "%s%"=="" exit/b
set c=%s:~0,1%
set t=%s:~1%
call set s=%%s:%c%=%%
if "%s%"=="%t%" set a=%a%%c%
if "%a:~2%"=="" goto l
echo %c%

No se puede ejecutar en W2008R2. La línea "conjunto de llamadas ..." se expande a "conjunto de llamadas t =% s: D =%" y aborta con el mensaje "La sintaxis del comando es incorrecta".
meden

@meden Lo siento, algunos errores tipográficos aparecieron en mi publicación. ¡El obvio fue que la publicación era más corta de lo que dije! Están arreglados ahora.
Neil

3

Pyth, 16 15 bytes

1 byte gracias a @ mbomb007

= rz1.xhtfq1 / zTzk
= rz1: fq1 / zTz1 2

Banco de pruebas.


2
Ni siquiera conozco a Pyth, pero si tú lo dices. : D
mbomb007 01 de

@ mbomb007 Ya sabes, el [1:2]truco.
Leaky Nun

Puede guardar un byte con en t<…2lugar de :…1 2. Puede guardar otro byte moviendo el =rz1de su primer uso, si también cambia 1a Z(por minúsculas en lugar de la salida mayúsculas): t<fq1/zT=rzZ2.
Anders Kaseorg el

3

En realidad, 19 bytes

;╗`ù╜ùc1=`░ε;(qq1@E

Pruébalo en línea!

Explicación:

;╗`ù╜ùc1=`░ε;(qq1@E
;╗                   push a copy of input to reg0
  `ù╜ùc1=`░          [v for v in s if
   ù╜ùc1=              s.lower().count(v.lower()) == 1]
           ε;(qq     append two empty strings to the list
                1@E  element at index 1 (second element)

3

C #, 129 128 bytes

char c(string i){var s=i.Where((n,m)=>i.ToLower().Where(o=>o==Char.ToLower(n)).Count()<2).ToArray();return s.Length>1?s[1]:' ';}

funciona bien. Desearía no tener que poner todo en minúsculas


Lanza una IndexOutOfRangeException cuando paso "Thisxthis" como argumento. Aparte de eso, creo que == 1 se puede cambiar a <2.
Yytsi

2

C # lambda con Linq, 63 bytes

s=>(s=s.ToUpper()).Where(c=>s.Count(C=>c==C)<2).Skip(1).First()

Usted debe ser capaz de reemplazar .Skip(1).First()con.ElementAt(1)
aloisdg dice Restablecer Mónica

Aún mejor, puede convertir a la lista y usar el índice.ToList()[1]
aloisdg dice Reinstate Monica el

Esto arroja una excepción para entradas como "", "AABB" y "AABBC", donde no hay un carácter coincidente en la segunda posición. Creo que necesitas FirstOrDefault.
Grax32

2

C #, 141 bytes

void p(){var x=Console.ReadLine().ToLower();var c=0;foreach(char i in x){if(x.Split(i).Length-1<2){if(++c==2){Console.WriteLine(i);break;}}}}

Sin descanso (el más pequeño), 135 bytes

void p(){var x=Console.ReadLine().ToLower();var c=0;foreach(char i in x){if(x.Split(i).Length-1<2){if(++c==2){Console.WriteLine(i);}}}}

Con for (;;), 150 bytes

void p(){for(;;){var x=Console.ReadLine().ToLower();var c=0;foreach(char i in x){if(x.Split(i).Length-1<2){if(++c==2){Console.WriteLine(i);break;}}}}}

Ungolfed con comentarios

void p()
{
    var x=Console.ReadLine().ToLower();//Get lowercase version of input from STDIN
    var c=0; //Create "count" integer
    foreach(char i in x){//For each char in input from STDIN
        if(x.Split(i).Length-1<2)//If current char occurs once in input from STDIN
        {
            if(++c==2){ //Add 1 to count and if count is 2
                Console.WriteLine(i); //Print result to STDOUT
                break; //Exit foreach
            } //End of IF
         } //End of IF
     } //End of FOREACH
} //End of VOID

TuukkaX ha guardado 12 bytes (cambie el conteo a c).

TuukkaX guardó 3 bytes (cambia la cadena a var).

TuukkaX guardó 4 bytes en "With for (;;)" (cambiado while (true) a for (;;)).

TuukkaX guardó 2 bytes (cambió c ++; if (c == 2) a if (++ c == 2)).

Bryce Wagner guardó 14 bytes (cambió x.ToCharArray () a x).


@ TuukkaX oh, de verdad. ¡gracias!
r3pear 01 de

Bienvenido a PPCG! Esa es una buena primera publicación! Dado que las reglas mencionan que las respuestas a este problema deberían ser funciones o programas completos, sus códigos requieren pequeños ajustes. También puede guardar bytes usando en varlugar de stringy teniendo algo como en clugar de count.
Yytsi

@ TuukkaX ¡Gracias de nuevo! En breve modificaré el código y cambiaré la cadena a var.
r3pear 01 de

@TuukkaX ¿Debo agregar algo como un programa vacío () {} ???
r3pear 01 de

Sí, ¡pero asigne un nombre de función de un byte para guardar bytes! :)
Yytsi

2

código de máquina x86, 43 bytes

En hexadecimal:

FC31C031C95641AC84C0740E3C6172F63C7A77F28066FFDFEBEC5EAC49740B89F751F2AE5974F44A77F1C3

La función toma un puntero a la cadena de entrada en (E) SI y un número entero en (E) DX y devuelve el carácter no repetitivo (E) DX-th o cero si no existe dicho carácter. Como efecto secundario, convierte la cadena en mayúsculas.

Desmontaje

fc             cld
31 c0          xor    eax,eax
31 c9          xor    ecx,ecx
56             push   esi
_loop0:                         ;Search for the NULL char,
41             inc    ecx       ;counting the length in the process
ac             lodsb
84 c0          test   al,al
74 0e          je     _break0   ;NULL found, break
3c 61          cmp    al,0x61   ;If char is
72 f6          jb     _loop0    ;between 'a' and 'z'
3c 7a          cmp    al,0x7a   ;convert this char
77 f2          ja     _loop0    ;to uppercase in-place
80 66 ff df    and    byte ptr [esi-0x1],0xdf
eb ec          jmp    _loop0
_break0:
5e             pop    esi       ;Reset pointer to the string
_loop:                          ;ECX=string length with NULL
ac             lodsb            ;Load next char to AL
49             dec    ecx
74 0b          je     _ret      ;End of string found, break (AL==0)
89 f7          mov    edi,esi   ;EDI points to the next char
51             push   ecx
f2 ae          repnz scasb      ;Search for AL in the rest of the string
59             pop    ecx
74 f4          je     _loop     ;ZF==1 <=> another instance found, continue
4a             dec    edx
77 f1          ja     _loop     ;If not yet the EDX-th non-rep char, continue
_ret:
c3             ret

2

APL, 32 bytes

{⊃1↓⍵/⍨1=+/∘.=⍨(⎕UCS ⍵)+32×⍵∊⎕A}

Pruébalo || Todos los casos de prueba

Explicación:

                (⎕UCS ⍵)+32×⍵∊⎕A  Add 32 to uppercase letters
            ∘.=⍨                    Make an equality matrix
          +/                        Check how many matches
    ⍵/⍨1=                           Keep elements with 1 match
  1↓                                Drop the first one
⊃                                   Return the second one

Estaba a punto de publicarlo con 16 bytes, pero me di cuenta de que tenía que distinguir entre mayúsculas y minúsculas ...


1
(⎕UCS ⍵)+32×⍵∊⎕A819⌶⍵
Adám

Nunca he visto a ese operador antes. ¿En qué versión funciona?
Woofmao

Se llama i-beam . Es un operador en todas las versiones de Dyalog APL. Originalmente era una función en versiones antiguas de APL de IBM para llamadas especiales al sistema IBM. ¿Consíguelo? IBM: ¿i-beam ?
Adám

Documentación para en general y para el servicio 819 ("819" ≈ "BIg"). Pruébalo en línea!
Adám

Bueno, he aprendido algo nuevo. tryapl.org no parece reconocerlo, entonces, ¿te importa si solo uso tu enlace TIO?
Woofmao


1

Mathematica, 49 bytes

Cases[Tally@ToUpperCase@#,{_,1}][[2,1]]~Check~""&

Función anónima. Toma una lista de caracteres como entrada. Ignora cualquier error que se genere.


1

JavaScript (Firefox 48 o anterior), 60 bytes

f=s=>(m=s.match(/(.).*\1/i))?f(s.replace(m[1],"","gi")):s[1]

Devuelve undefinedsi solo hay cero o uno caracteres que no se repiten. Funciona eliminando entre mayúsculas y minúsculas todas las apariciones de caracteres que aparecen más de una vez en la cadena. Se basa en una extensión de Firefox no estándar que se eliminó en Firefox 49. 119 Versión de 91 bytes ES6:

f=s=>(m=s.match(/(.).*?(\1)(.*\1)?/i))?f((m[3]?s:s.replace(m[2],"")).replace(m[1],"")):s[1]

Busca recursivamente todos los caracteres que aparecen al menos dos veces en la cadena. Si el carácter aparece exactamente dos veces, ambas ocurrencias se eliminan; de lo contrario, solo se elimina la primera ocurrencia (las otras ocurrencias se eliminarán más adelante). Esto permite que las ocurrencias tengan un caso de diferencia.


Creo que realmente puede adaptar su respuesta de Firefox 48 para que sea compatible con ES6 reemplazándola m[1]pornew RegExp(`${m[1]}`,"gi")
Value Ink el

@ KevinLau-notKenny Eso no funcionaría para caracteres especiales, y me costó 33 bytes el caso especial, llevándome hasta 93, por desgracia.
Neil

noooooo no los personajes especiales! He tenido que editar mi respuesta Ruby para acomodarlos también, ahora.
Value Ink

1

J, 25 bytes

(1{2{.]-.]#~1-~:)@tolower

Uso

   f =: (1{2{.]-.]#~1-~:)@tolower
   f 'DEFD'
f
   f 'FEED'
d
   f 'This is an example input sentence.'
x
   f '...,,,..,,!@'
@
   f 'ABCDefgHijklMNOPqrsTuVWxyz'
b
   f 'AAAAAABBBBB'

   f 'Thisxthis'

   f 'This this.'
.

Explicación

(1{2{.]-.]#~1-~:)@tolower  Input: s
                  tolower  Converts the string s to lowercase
              ~:           Mark the indices where the first time a char appears
            1-             Complement it
         ]                 Identity function to get s
          #~               Copy only the chars appearing more than once
      ]                    Identity function to get s
       -.                  Remove all the chars from s appearing more than once
   2{.                     Take the first 2 chars from the result (pad with empty string)
 1{                        Take the second char at index 1 and return it

1

Bash, 58 bytes

tr A-Z a-z>t
tr -dc "`fold -1<t|sort|uniq -u`"<t|cut -c2

Precaución: Esto crea un archivo temporal llamado t . Si ya existe, se sobrescribirá.


1

C, 174 bytes

int c(char*s){int y=128,z=256,c[384],t;memset(c,0,z*6);for(;t=toupper(*s);s++){c[t]++?c[t]-2?0:c[z+(c[y+c[z+t]]=c[y+t])]=c[z+t]:c[z]=c[y+(c[z+t]=c[z])]=t;}return c[y+c[y]];}

Esta no es la implementación más corta, pero bastante eficiente. En esencia, utiliza una lista de doble enlace para mantener el conjunto ordenado de caracteres candidatos y escanea la cadena de entrada solo una vez. Devuelve el código de caracteres o cero si no se encuentra ninguno.

Una versión un poco sin golf:

int c(char*s)
{
    int y=128,z=256,c[384],t;
    //It's basically c[3][128], but with linear array the code is shorter

    memset(c,0,z*6);

    for(;t=toupper(*s);s++)
    {
        c[t]++ ?        // c[0][x] - number of char x's occurrence
            c[t] - 2 ?  // > 0
                0       // > 1 - nothing to do  
                : c[z + (c[y + c[z + t]] = c[y + t])] = c[z + t]  // == 1 - remove char from the list
            : c[z] = c[y + (c[z + t] = c[z])] = t; // == 0 - add char to the end of the list
    }
    return c[y + c[y]];
}

1

C #, 143 bytes

char c(string s){var l=s.Select(o=>Char.ToLower(o)).GroupBy(x=>x).Where(n=>n.Count()<2).Select(m=>m.Key).ToList();return l.Count()>1?l[1]:' ';}

1

TSQL, 128 bytes

Golfizado:

DECLARE @ varchar(99)=',,zzzbb@kkkkkkJgg'

,@i INT=99WHILE @i>1SELECT
@i-=1,@=IIF(LEN(@)>LEN(x)+1,x,@)FROM(SELECT
REPLACE(@,SUBSTRING(@,@i,1),'')x)x PRINT SUBSTRING(@,2,1)

Sin golf:

DECLARE @ varchar(99)=',,zzzbb@kkkkkkJgg'

,@i INT=99

WHILE @i>1
  SELECT
    @i-=1,@=IIF(LEN(@)>LEN(x)+1,x,@)
  FROM
    (SELECT 
       REPLACE(@,SUBSTRING(@,@i,1),'')x
    )x

PRINT SUBSTRING(@,2,1)

Violín


1

Ruby, 53 bytes

La entrada es STDIN, la salida es STDOUT. En Ruby, las posiciones fuera de índice en una matriz o cadena devuelvennil , lo que no se imprime.

String#countes una función extraña en Ruby porque en lugar de contar el número de ocurrencias para la cadena que se pasó, cuenta el número de ocurrencias para cada letra en esa cadena. Suele ser molesto, pero esta vez podemos usarlo para nuestro beneficio. String#swapcaseintercambia letras mayúsculas y minúsculas.

$><<gets.chars.reject{|c|$_.count(c+c.swapcase)>1}[1]

Versión anterior que no era segura contra caracteres especiales como .- 46 bytes

$><<gets.chars.reject{|c|$_=~/#{c}.*#{c}/i}[1]

1

Java 8, 172157 bytes

(String s)->{s=s.toLowerCase();for(char i=0,c;s.length()>0;s=s.replace(c+"","")){c=s.charAt(0);if(!s.matches(".*"+c+".*"+c+".*")&&++i>1)return c;}return' ';}

-15 bytes ... Dang, yo era malo jugando al golf en aquel entonces. ;)

Explicación:

Pruébalo aquí

(String s)->{                          // Method with String parameter and character return-type
  s=s.toLowerCase();                   // Make the input-String lowercase
  for(char i=0,c;s.length()>0;         // Loop over the characters of `s`
      s=s.replace(c+"","")){           // And after every iteration, remove all occurrences of the previous iteration
    c=s.charAt(0);                     // Get the current first character
    if(!s.matches(".*"+c+".*"+c+".*")  // If it doesn't occur more than once
     &&++i>1)                          // And this was the second one we've found
      return c;                        // Return this second characters
  }                                    // End of loop
  return' ';                           // Else: return an empty character/nothing
}                                      // End of method

1

R , 79 bytes

function(z){y=tolower(el(strsplit(z,"")));x=table(y);y[y%in%names(x[x==1])][2]}

Pruébalo en línea!

Definitivamente siento que algo se puede jugar aquí. Pero realmente disfruté este desafío.

Esta respuesta divide la cadena en un vector de caracteres, los cambia a minúsculas y los tabula (los cuenta). Los caracteres que aparecen una vez se seleccionan y se comparan con los caracteres dentro del vector mencionado anteriormente, luego el segundo valor verdadero se devuelve como salida. Una cadena vacía o una cadena sin caracteres repetidos genera NA.



1

K (oK) / K4 , 11 bytes

Solución:

*1_&1=#:'=_

Pruébalo en línea!

Explicación:

*1_&1=#:'=_ / the solution
          _ / convert input to lowercase
         =  / group alike characters
      #:'   / count (#:) each group
    1=      / 1 equal to length of the group?
   &        / where true
 1_         / drop the first
*           / take the first


0

Perl, 75 bytes

 my$s=<>;chomp$s;my$c;for my$i(split//,$s){my$m=@{[$s=~/$i/gi]};$m<2and++$c>=2and say$i and last}

0

Javascript (usando una biblioteca externa) (107 bytes)

Aplasté esto usando una biblioteca que escribí. No estoy seguro si tengo que contar la declaración de la variable "s", que es la cadena en cuestión.

(s)=>_.From(s).ToLookup(y=>y.toLowerCase(),z=>z).Where(g=>g.Value.Count()==1).Select(x=>x.Key).ElementAt(1)

Esto manejará una entrada de cadena vacía, una entrada con solo un carácter que no se repite y una entrada con más de 2 caracteres que no se repiten

Imagen 1


¿Tiene un enlace a la biblioteca en cuestión? Además, al tratarse de un código de golf, debes eliminar los espacios en blanco donde puedas
Value Ink el

Hola, sí, es github.com/mvegh1/Enumerable . No hay documentos todavía. Lo siento, voy a limpiar esta respuesta para reducir la mayor cantidad de espacios en blanco
applejacks01

Probablemente debería mencionarlo y vincularlo en el cuerpo de la respuesta. Además, con respecto al bytecount, el consenso es ponerlo en una lambda anónima (así s=> ...)
Value Ink

Está bien, no hay problema. No quería ofender a nadie al vincularme a mi código, pero sí mencioné que usé mi biblioteca. Voy a actualizar mi respuesta con la lambda, gracias por dejarme saben
applejacks01

0

Clojure, 109 bytes

#(let[s(clojure.string/lower-case %)](or(second(remove(set(map(fn[[k v]](if(> v 1)k))(frequencies s)))s))""))

Ough, espero que haya una manera más sucinta.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.