Encuentra la carta que falta


27

Pautas

Tarea

Escriba un método que tome una matriz de letras consecutivas (crecientes) como entrada y que devuelva la letra que falta en la matriz (listas en algunos idiomas).


Reglas

  • Este es el código de golf, por lo que gana la respuesta más corta en bytes.
  • Siempre obtendrás una matriz válida
  • Siempre habrá exactamente una letra faltante
  • La longitud de la matriz siempre será al menos 2.
  • La matriz siempre contendrá letras en un solo caso (mayúsculas o minúsculas)
  • Debe generar en el mismo caso (mayúsculas o minúsculas) que la entrada es
  • La matriz siempre irá solo una letra por vez (omitiendo la letra que falta)
  • La longitud de la matriz estará entre 2 y 25
  • El primer o el último elemento de la matriz nunca faltará

Ejemplos

['a','b','c','d','f'] -> 'e'

['O','Q','R','S'] -> 'P'

['x','z'] -> 'y'

['a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','w','x','y','z'] -> 'v'


¿Puedo tomar una cuerda en su lugar?
Leaky Nun

@LeakyNun Las cadenas son matrices de caracteres, así que sí.
Amorris

1
¿Puede la salida ser una matriz que contiene el carácter que falta (por ejemplo, para la entrada ['a','b','c','d','f','g'], salida ['e'], si eso
acorta

1
@ Mr.Xcoder Una cadena es solo una serie de caracteres, así que sí
Amorris

2
La regla cuatro es simplemente un subconjunto de la regla ocho y puede eliminarse (al menos, si coloca la palabra "inclusivo" al final de la regla ocho).
NH.

Respuestas:



11

C # (.NET Core) , 48 47 46 bytes, entrada como matriz de caracteres

s=>{for(int i=0;s[++i]==++s[0];);return s[0];}

Pruébalo en línea!

Explicación: el primer elemento de la matriz se incrementa, así como un puntero que itera los siguientes elementos. Cuando tanto el primer elemento como el elemento actual son diferentes, devuelve el primer elemento.

C # (.NET Core) , 58 56 50 bytes, entrada como cadena

s=>{var c=s[0];while(s.IndexOf(++c)>=0);return c;}

Pruébalo en línea!

Solución anterior de 58 bytes (mencionada en el primer comentario):

s=>{for(int i=1;;i++)if(s[i]-s[0]>i)return(char)(s[i]-1);}

Algoritmos que usan System.Linq

Los siguientes algoritmos deben agregar using System.Linq; (18 bytes) al recuento de bytes y, por lo tanto, son más largos.

Este me gustó bastante (52 + 18 bytes):

s=>{int i=0;return(char)(s.First(c=>c-s[0]>i++)-1);}

Y también tiene una solución de una línea (45 + 18) bytes:

s=>(char)(s.Where((c,i)=>c-s[0]>i).First()-1)

Y una solución muy inteligente (37 + 18) bytes, cortesía de Ed'ka:

s=>s.Select(e=>++e).Except(s).First()

1
¿Esto no fallará al compilar con no todas las rutas de código devuelven un valor? ¡Pero +1 para la verificación de comparación con s[i]-s[0], bastante inteligente!
TheLethalCoder

@TheLethalCoder No fallará ya que el forciclo no tiene una condición de detención, por lo que seguirá iterando hasta que la ifcondición se evalúe como true.
Charlie

1
Puede guardar 8 bytes de esta manera: a=>{int i=0;for(;a[++i]-a[0]<=i;);return--a[i];}(cuando toma la entrada como char[]). No gracias a mí por cierto, gracias al comentario de @Nevay sobre mi respuesta de Java 8 .
Kevin Cruijssen

1
@KevinCruijssen encontró una manera de guardar dos bytes más tomando la entrada como una matriz de caracteres.
Charlie

1
Versión más corta de Linq:s=>s.Select(e=>++e).Except(s).First()
Ed'ka

8

Alice , 10 bytes

/X.
\ior@/

Pruébalo en línea!

Explicación

Esto es solo un marco para programas lineales que operan completamente en modo Ordinal (procesamiento de cadenas):

/...
\.../

El código lineal real es entonces:

i.rXo@

Que hace:

i   Read all input.
.   Duplicate.
r   Range expansion. If adjacent letters don't have adjacent code points, the
    intermediate code points are filled in between them. E.g. "ae" would turn
    into "abcde". For the inputs in this challenge, this will simply insert
    the missing letter.
X   Symmetric set difference. Drops all the letters that appear in both strings,
    i.e. everything except the one that was inserted by the range expansion.
o   Output the result.
@   Terminate the program.


7

Ruby, 21 caracteres

->a{[*a[0]..a[-1]]-a}

Devuelve una matriz de un solo elemento, de acuerdo con el comentario del propietario de la pregunta .

Ejecución de muestra:

irb(main):001:0> ->a{[*a[0]..a[-1]]-a}[['a','b','c','d','f']]
=> ["e"]

Pruébalo en línea!


7

Java 8, 70 57 56 48 46 bytes

a->{for(int i=0;++a[0]==a[++i];);return a[0];}

-14 (70 → 56) y -2 (48 → 46) bytes gracias a @CarlosAlejo .
-8 (56 → 48) bytes gracias a @Nevay .

Explicación:

Pruébalo aquí

a->{            // Method with char-array parameter and char return-type
  for(int i=0;  //  Start index-integer at 0 and loop as long as
    ++a[0]      //   the previous character + 1 (by modifying the character at index 0)
    ==a[++i];   //   equals the next character (by raising the index by 1 before checking)
  );            //  End of loop
  return a[0];  //  Return the now modified character at index 0 in the array
}               // End of method

1
Puede usar una conversión implícita en lugar de una conversión explícita para guardar 8 bytes a->{int i=0;for(;a[++i]-a[0]<=i;);return--a[i];}.
Nevay

6

C (gcc) , 3335 36 48 60 60 bytes

Todas las optimizaciones deben desactivarse y solo en GCC de 32 bits.

f(char*v){v=*v+++1-*v?*v-1:f(v);}

Toma la entrada como una cadena.

Pruébalo en línea!


2
"Todas las optimizaciones deben desactivarse y solo en GCC de 32 bits". es una forma muy indirecta de decir que esto no funciona (solo parece funcionar debido a UB)
sehe

Yo diría que foo(char*a){return*a+1==a[1]?foo(a+1):++*a;}es bastante bueno; Solo 1 char más corto que el más naturalfoo(char*a){while(*a+1==a[1])a++;return++*a;}
sehe

@sehe comportamiento indefinido constante se considera aceptable en PPCG
Keyu Gan

5

Python 3 , 74 62 58 44 40 bytes

-12 bytes gracias a Erik the Outgolfer. -18 bytes gracias a Leaky Nun. -4 bytes gracias a musicman523.

Toma la entrada como una cadena de bytes.

lambda s:chr(*{*range(s[0],s[-1])}-{*s})

Pruébalo en línea!

Otra solución genial:

lambda s:chr(*{*range(*s[::~-len(s)])}-{*s})

1
.difference({*s})->-{*s}
Erik the Outgolfer




1
Su solución es lo que estaba
buscando,

4

Mathematica, 46 bytes

Min@Complement[CharacterRange@@#[[{1,-1}]],#]&

Creo que eso Min@Complement[CharacterRange@@#[[{1,-1}]],#]&salvaría un byte.
LegionMammal978

@ LegionMammal978 en realidad 2!
J42161217

3

JavaScript (ES6), 70 bytes

Entrada como una matriz de caracteres

(a,p)=>a.some(c=>(q=p+1,p=c.charCodeAt(),p>q))&&String.fromCharCode(q)

Menos golf

a=>{
  p = undefined;
  for(i = 0; c = a[i]; i++)
  {
    q = p+1
    p = c.charCodeAt()
    if (p>q)
      return String.fromCharCode(q)
  }
}

Prueba

F=(a,p)=>a.some(c=>(q=p+1,p=c.charCodeAt(),p>q))&&String.fromCharCode(q)

function update() {
  var a0=A0.value.charCodeAt()
  var a1=A1.value.charCodeAt()
  if (a1>a0) {
    var r = [...Array(a1-a0+1)]
      .map((x,i)=>String.fromCharCode(a0+i))
      .filter(x => x != AX.value)
    I.textContent = r.join('') + " => " + F(r)
  }
  else {
    I.textContent=''
  }
}

update()
input { width: 1em }
Range from <input id=A0 value='O' pattern='[a-zA-Z]' length=1 oninput='update()'>
to <input id=A1 value='T' pattern='[a-zA-Z]' length=1 oninput='update()'>
excluding <input id=AX value='Q' pattern='[a-zA-Z]' length=1 oninput='update()'>
<pre id=I></pre>



3

Retina , 33 25 bytes

$
¶$_
T`p`_p`.*$
D`.
!`.$

Pruébalo en línea! Funciona con cualquier rango de caracteres ASCII. Editar: guardado 8 bytes gracias a @MartinEnder. Explicación: La primera etapa duplica la entrada. El segundo disminuye todos los caracteres de la copia en 1 punto de código. La tercera etapa elimina todos los caracteres de la copia que aún aparecen en el original. Esto solo deja la entrada original, el carácter que precede al primer carácter de la entrada original y el carácter que falta. La última etapa simplemente coincide con el personaje que falta.


Aquí hay 25, usando la misma idea básica: tio.run/##K0otycxL/P9fhevQNpV4rpCEgoT4ggQ9LRUulwQ9LsUEPZX///… (Estoy disminuyendo la segunda línea porque eso ahorra un byte y luego encuentro el carácter único usando deduplicación.)
Martin Ender

@MartinEnder Deduplication es exactamente lo que siempre quise, y ya olvidé que Retina lo tiene, suspiro ... (Sé que incrementar la primera línea toma un byte más que disminuir la segunda línea, pero acortó la expresión regular del partido).
Neil

3

SWI Prolog, 124 bytes

m([H|T]):-n(H,N),c(T,N),!,m(T).
n(I,N):-o(I,C),D is C+1,o(N,D).
c([N|_],N).
c(_,N):-print(N),!,fail.
o(C,O):-char_code(C,O).

Ejemplos:

?- m(['a','b','c','d','f']).
e
false.

?- m(['O','Q','R','S']).
'P'
false.

?- m(['x','z']).
y
false.

?- m(['a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','w','x','y','z']).
v
false.

Pequeña explicación:

El mes el procedimiento "principal", nproduce el siguiente carácter esperado en la lista. La ccomparación sí: si las expectativas coinciden con el siguiente elemento, continúe, de lo contrario imprima el carácter esperado y salte por la ventana.


1
Más corto que fail: 0=1.
mat

3

C ++ 14, biblioteca estándar, tipo de contenedor genérico ( 87 86 bytes)

[](auto a){return++*adjacent_find(begin(a),end(a),[](auto a,auto b){return a+1!=b;});}

::stdSe supone el tipo de contenedor del espacio de nombres (por ejemplo std::string, std::listo std::vector. De lo contrario using namespace std;, se supondría algo similar.

Gracias a @Ven, con un poco de pirateo de preprocesadores, lo obtienes bajarlo a 82 bytes (1 nueva línea)

#define x [](auto a,int b=0){return++
x *adjacent_find(begin(a),end(a),x a!=b;});}

Míralo Live On Coliru

C ++ 14 sin biblioteca estándar (todavía genérico, 64 63 bytes)

[](auto& a){auto p=*begin(a);for(auto c:a)if(c!=p++)return--p;}

Nuevamente, debe ayudar a buscar nombres solo si el tipo de contenedor no es del espacio de nombres ::std (o está asociado con él)

Live On Coliru para std::stringej.

Live On Colirupor char const[]ej.


Debe poner un espacio entre el texto tachado y el siguiente texto.
CJ Dennis

@CJDennis Hecho. Por cierto, su representante actual (2469) es un número hermoso (siendo 3 * 823 y también visualmente emparejado como (24) (69) que es (2 2 2 3) (3 23))
sehe

2

Carbón , 18 bytes

Fγ¿¬∨∨‹ι⌊θ›ι⌈θ№θιι

Pruébalo en línea! El enlace es a la versión detallada del código. Toma la entrada como una cadena. Funciona con cualquier secuencia casi contigua de caracteres ASCII.


2

C #, 104 bytes

using System.Linq;a=>(char)Enumerable.Range(a.Min(),a.Max()-a.Min()).Except(a.Select(c=>(int)c)).First()

Versión completa / formateada:

using System.Linq;

namespace System
{
    class P
    {
        static void Main()
        {
            Func<char[], char> f = a =>
                (char)Enumerable.Range(a.Min(), a.Max() - a.Min())
                                .Except(a.Select(c=>(int)c))
                                .First();

            Console.WriteLine(f(new[] { 'a', 'b', 'c', 'd', 'f' }));

            Console.ReadLine();
        }
    }
}

Una versión Linq muy inteligente de Ed'ka :s=>s.Select(e=>++e).Except(s).First()
Charlie

@CarlosAlejo Vi que lo agregaste a tu respuesta, así que no actualizaré la mía, pero sí, es muy inteligente. Mucho más corto que mi versión de hacerlo.
TheLethalCoder

2

MATL, 8 7 bytes

1 byte guardado gracias a @Luis

tdqf)Qc

Pruébalo en MATL Online

Explicación

      % Implicitly grab the input as a string
t     % Duplicate the string
d     % Compute the differences between successive characters
q     % Subtract 1 from each element
f     % Get the locations of all non-zero characters (1-based index)
)     % Extract that character from the string
Q     % Add one to get the next character (the missing one)
c     % Convert to character and display

@LuisMendo Impresionante, gracias!
Suever

2

Excel, 110 + 2 = 112 bytes

=CHAR(CODE(LEFT(A1))-1+MATCH(0,IFERROR(FIND(CHAR(ROW(INDIRECT(CODE(LEFT(A1))&":"&CODE(RIGHT(A1))))),A1),0),0))

Debe ingresarse como una fórmula de matriz ( Ctrl+ Shift+ Enter) que agrega llaves { }en cada extremo, agregando dos bytes. La entrada es como una cadena de entrada A1, lo cual está bien por OP .

Esta no es la respuesta más corta con diferencia (Excel rara vez lo es) pero me gusta ver si se puede hacer.



2

CJam , 6 bytes (programa completo) / 7 bytes (bloque de código)

q),^W=

Pruébalo en línea!

Este es un programa completo de CJam que lee la cadena de entrada desde la entrada estándar e imprime la letra que falta en la salida estándar. CJam en realidad no tiene "métodos", que es lo que pide el desafío, pero lo más cercano probablemente sería un bloque de código ejecutable, como este:

{),^W=}

Pruébalo en línea!

Este bloque de código, cuando se evalúa, toma la entrada como una cadena (es decir, una matriz de caracteres) en la pila y devuelve el carácter faltante también en la pila.


Explicación: en el programa completo, qlee la cadena de entrada y la coloca en la pila. )luego saca el último carácter de la cadena de entrada, y el operador de rango lo ,convierte en una matriz que contiene todos los caracteres con puntos de código debajo (incluidas todas las letras anteriores en el alfabeto). Así, por ejemplo, si la entrada fue cdfgh, entonces después de ),la pila contendría las cadenas cdfg(es decir, la entrada con la última letra eliminada) y ...abcdefg, donde ...representa un grupo de caracteres con códigos ASCII a continuación a(es decir, todos los caracteres debajo de la última entrada eliminada carta).

El operador de diferencia de conjunto simétrico ^combina estas cadenas en una sola cadena que contiene exactamente los caracteres que aparecen en una de las cadenas, pero no en ambas. Conserva el orden en que aparecen los caracteres en las cadenas, por lo que para la entrada de ejemplo cdfg, el resultado posterior ),^será ...abe, donde ...nuevamente representa un grupo de caracteres con los códigos ASCII a continuación a. Finalmente, W=solo extrae el último carácter de esta cadena, que es exactamente el carácter faltante eque queríamos encontrar (y descarta el resto). Cuando finaliza el programa, el intérprete de CJam imprime implícitamente el contenido de la pila.


Bonus: GolfScript , 6 bytes (programa completo)

),^-1>

Pruébalo en línea!

Resulta que casi el mismo código también funciona en GolfScript. Guardamos un byte en la versión completa del programa debido a la entrada implícita de GolfScript, pero perdemos un byte porque, a diferencia de CJamW , GolfScript no tiene una variable útil de una sola letra inicializada en -1.

Además, CJam tiene tipos enteros y de caracteres separados (y las cadenas son solo matrices que contienen caracteres), mientras que GolfScript solo tiene un tipo entero único (y tiene un tipo de cadena especial que se comporta de manera algo diferente de las matrices normales). El resultado de todo esto es que, si queremos que el intérprete de GolfScript imprima la letra faltante real en lugar de su número de código ASCII, debemos devolver una cadena de un solo carácter en lugar de solo el carácter en sí. Afortunadamente, hacer ese cambio aquí solo requiere reemplazar el operador de indexación =con el operador de truncamiento izquierdo de la matriz / cadena >.

Por supuesto, gracias a la E / S implícita de GolfScript, el código anterior también se puede usar como un fragmento que lee una cadena de la pila y devuelve una cadena de un solo carácter que contiene la letra que falta. O, mejor dicho, cualquier fragmento que tome una sola cadena en la pila como argumento, y devuelva su salida como una cadena imprimible en la pila, también es un programa completo de GolfScript.


66
Los fragmentos de código no están permitidos de manera predeterminada ; solo funciones y programas completos son. Entonces probablemente necesite ese q(programa) o {...}(bloque). +1 para el enfoque sin embargo
Luis Mendo

¡Esto es muy inteligente!
Esolanging Fruit

2

Casco , 6 bytes

→S-(ḣ→

Pruébalo en línea!

Esta función toma una cadena (lista de caracteres) como entrada y devuelve un carácter como salida.

Explicación

→S-(ḣ→
    ḣ→    Get the list of all characters from the null byte to the last character of the input
 S-       Subtract the input from this list
→         Get the last element of the result

2

Python 2 - 76 bytes

Pierde a la solución existente de Python 2, pero es un enfoque ligeramente diferente, así que pensé en publicarlo de todos modos:

lambda c:[chr(x)for x in range(ord(c[0]),ord(c[0]+26)if chr(x)not in c][0]

2

8vo , 99 bytes

Razón fundamental

Si la distancia entre letras es mayor que dos, entonces falta una letra. La distancia entre letras se obtiene calculando la diferencia entre el código ASCII de cada letra.

Código

: f ' nip s:each repeat over n:- 2 n:= if n:1+ "" swap s:+ . reset 1 then depth n:1- while! reset ;

Versión sin golf

: f \ s -- c 
  ' nip s:each    \ convert each letter into its ASCII code and put them on stack
  repeat
    over
    n:- 2 n:=     \ check if there is a missing letter 
    if            
      n:1+        \ compute the ASCII code of missing letter
      "" swap s:+ \ convert ASCII code into printable character
      .           \ print out the missing letter
      reset 1     \ set condition to exit from while!
    then
    depth n:1-    \ verify if there are letters to check
  while!          
  reset           \ clean stack
;

Uso y ejemplos

ok> "abcdf" f
e
ok> "OQRS" f
P
ok> "xz" f
y
ok> "abcdefghijklmnopqrstuwxyz" f
v
ok> "ab" f

ok> "def" f

ok>

2

JavaScript (ES6), 64 bytes

Toma la entrada como una cadena.

s=>(g=p=>(c=String.fromCharCode(n++))<s[p]?p?c:g(p):g(p+1))(n=0)

¿Cómo?

  • Inicialización: Comenzamos con n = 0 y p = 0 y llamamos a la función recursiva g () .

    g = p =>                                   // given p
      (c = String.fromCharCode(n++)) < s[p] ?  // if the next char. c is not equal to s[p]:
        p ?                                    //   if p is not equal to zero:
          c                                    //     step #3
        :                                      //   else:
          g(p)                                 //     step #1
      :                                        // else:
        g(p + 1)                               //   step #2
  • Paso # 1: Incrementamos n hasta que c = String.fromCharCode(n)sea ​​igual al primer carácter de la cadena de entrada s [0] .

  • Paso # 2: Ahora que estamos sincronizados, incrementamos tanto n como p al mismo tiempo hasta que c = String.fromCharCode(n)ya no sea igual a s [p] .

  • Paso 3: devolvemos c : el carácter esperado que no se encontró.

Casos de prueba


1

J, 20 bytes

{&a.>:I.1 0 1&E.a.e.
  • a.e. máscara booleana para las letras de entrada en el conjunto de caracteres ascii
  • 1 0 1&E. nueva máscara booleana que indica si la secuencia 101 comienza en ese índice, es decir, encuentra cualquier lugar donde comienza una secuencia de "omisión"
  • I. el índice de esa coincidencia, es decir, el carácter anterior al omitido
  • >: incremente en 1, es decir, el índice del carácter omitido dentro del conjunto de caracteres ascii
  • {&a. seleccione ese índice del conjunto de caracteres ascii, es decir, devuelva el carácter omitido

Pruébalo en línea!


Eso me parece un fragmento.
Adám

@ Adám Está escrito en un estilo tácito (sin puntos), que creo que cuenta como "funcional" en lugar de un fragmento. Lo mejor que puedo decir es que no es más un fragmento que su solución APL (pero no sé dyalog, así que tome lo que digo con un grano de sal).
zgrep

@ Adám sí lo es, en el sentido de que no puede asignarse a una variable pero asume una entrada en su lado derecho. ¿No es esto legal? pregunté sobre eso en algún lugar y me dijeron que estaba bien
Jonah

Entiendo que APL / J / K es que el código debe poder residir en un nombre, ya sea por asignación o como cuerpo, un verbo / función explícito (sin embargo, la forma explícita también debe tener una entrada explícita). El fragmento es un código que asume valores en variables y / o necesita pegarse en una línea, pero no puede sostenerse por sí solo.
Adám

@zgrep No, este código es explícito (no tácito), pero le falta la referencia a su argumento en el extremo derecho. Mi función APL es una función tácita completa que se puede asignar o poner entre paréntesis.
Adám

1

ES6, 125 bytes:

(a=>((s,f)=>(r=(i,b)=>a[i]?r(i+1,b||(s[f](i)-s[f](i-1)-1&&String.fromCharCode(s[f](i-1)+1))):b)(1,0))(a.join(""),"charCodeAt"))

http://jsbin.com/vasoqidawe/edit?console

La función devuelta debe llamarse con una matriz

(["a","c"])

uno podría guardar otros 9 bytes eliminando .join ("") y pasando una cadena:

("ac")

ES6, 108 bytes:

(a=>((s,f,o)=>(a.find((_,i)=>(o?++o:o=s[f](i))!==s[f](i)),String.fromCharCode(o)))(a.join(""),'charCodeAt'),0))

http://jsbin.com/tudiribiye/edit?console


1
atar ??? en el código de golf?
edc65

@ edc65 ¿qué tiene de malo? (lo siento si esto es n00b, pero ese es mi primer golf :))
Jonas Wilms

@ edc65 pero probablemente tengas razón, al eliminarlo se guardaron 4 bytes ...
Jonas Wilms

a.join("")podría sera.join``
user2428118


1

Python 2 , 69 bytes

lambda a:chr((ord(a[0])+ord(a[-1]))*-~len(a)/2-sum(ord(x)for x in a))

Pruébalo en línea!

Algunas explicaciones Como conocemos el primer y el último elemento de la lista, podemos calcular fácilmente la suma de los códigos de todos los caracteres en list + the missed char(usando fórmulas de resumen de progresión aritmética ). La diferencia entre esta suma y la suma de los códigos de todos los caracteres en el listda el código de la letra perdida.



1

APL (Dyalog) , 17 bytes

(⊃⎕AV/⍨∨\∧~)⎕AV∘∊

Pruébalo en línea!

⎕AV∘∊ Boole: cada carácter de la A Tomic V ector (conjunto de caracteres) miembro de la discusión?

(... ) aplique la siguiente función tácita:

 el primer elemento de

⎕AV la A tomic V ector (el juego de caracteres)

/⍨ cual

∨\ sigue la inicial (miembro del argumento)

 pero

~ no es (un miembro del argumento)

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.