Trova la lettera mancante


27

Linee guida

Compito

Scrivi un metodo che accetta come input una matrice di lettere consecutive (crescenti) e che restituisce la lettera mancante nella matrice (elenchi in alcune lingue).


Regole

  • Questo è il codice golf, quindi vince la risposta più breve in byte!
  • Otterrai sempre un array valido
  • Ci mancherà sempre esattamente una lettera
  • La lunghezza dell'array sarà sempre almeno 2.
  • L'array conterrà sempre le lettere in un solo caso (maiuscolo o minuscolo)
  • È necessario eseguire l'output nello stesso caso (maiuscolo o minuscolo) dell'input
  • L'array andrà sempre solo una lettera alla volta (saltando la lettera mancante)
  • La lunghezza dell'array sarà compresa tra 2 e 25
  • Il primo o l'ultimo elemento dell'array non mancherà mai

Esempi

['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'


Posso prendere una stringa invece?
Leaky Nun,

@LeakyNun Le stringhe sono array di caratteri, quindi sì.
Amorris,

1
L'output può essere un array contenente il carattere mancante (ad esempio: per l'input ['a','b','c','d','f','g'], l'output ['e'], se ciò accorcia il codice?
Mr. Xcoder

1
@ Mr.Xcoder Una stringa è solo una matrice di caratteri, quindi sì
Amorris,

2
La regola quattro è semplicemente un sottoinsieme della regola otto e può essere rimossa (almeno, se si mette la parola "inclusivo" alla fine della regola otto).
NH.

Risposte:



11

C # (.NET Core) , 48 47 46 byte, input come array di caratteri

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

Provalo online!

Spiegazione: viene incrementato il primo elemento dell'array e un puntatore che scorre i seguenti elementi. Quando sia il primo elemento che l'elemento corrente sono diversi, restituisce il primo elemento.

C # (.NET Core) , 58 56 50 byte, immessi come stringa

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

Provalo online!

Soluzione precedente a 58 byte (indicata nel primo commento):

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

Algoritmi che utilizzano System.Linq

I seguenti algoritmi devono aggiungere using System.Linq;(18 byte) al conteggio dei byte e quindi sono più lunghi.

Mi è abbastanza piaciuto questo (52 + 18 byte):

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

E hai anche una soluzione da 1 linea (45 + 18) byte:

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

E una soluzione molto intelligente (37 + 18) -byte, per gentile concessione di Ed'ka:

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

1
Non sarà possibile compilare questo con non tutti i percorsi di codice restituiscono un valore? Ma +1 per il confronto con s[i]-s[0], abbastanza intelligente!
TheLethalCoder il

@TheLethalCoder Non fallirà in quanto il forloop non ha una condizione di arresto, quindi continuerà a scorrere fino a quando la ifcondizione non viene valutata true.
Charlie

1
È possibile salvare 8 byte in questo modo: a=>{int i=0;for(;a[++i]-a[0]<=i;);return--a[i];}(quando si prende l'input come char[]). Non grazie a me a proposito, grazie al commento di @Nevay sulla mia risposta Java 8 .
Kevin Cruijssen,

1
@KevinCruijssen ha trovato un modo per salvare altri due byte prendendo l'input come array di caratteri.
Charlie,

1
Versione più breve di Linq:s=>s.Select(e=>++e).Except(s).First()
Ed'ka,

8

Alice , 10 byte

/X.
\ior@/

Provalo online!

Spiegazione

Questo è solo un framework per programmi lineari che funzionano interamente in modalità Ordinale (elaborazione di stringhe):

/...
\.../

Il vero codice lineare è quindi:

i.rXo@

Che fa:

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

Rubino, 21 caratteri

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

Restituisce una matrice a singolo elemento, in base al commento del proprietario della domanda .

Esecuzione di esempio:

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

Provalo online!


7

Java 8, 70 57 56 48 46 byte

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

-14 (70 → 56) e -2 (48 → 46) byte grazie a @CarlosAlejo .
-8 (56 → 48) byte grazie a @Nevay .

Spiegazione:

Provalo qui.

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
È possibile utilizzare un cast implicito anziché un cast esplicito per salvare 8 byte a->{int i=0;for(;a[++i]-a[0]<=i;);return--a[i];}.
Nevay,

6

C (gcc) , 3335 36 48 60 byte

Tutte le ottimizzazioni devono essere disattivate e solo su GCC a 32 bit.

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

Prendi input come stringa.

Provalo online!


2
"Tutte le ottimizzazioni devono essere disattivate e solo su GCC a 32 bit." è un modo molto indiretto per dire che non funziona (sembra funzionare solo a causa di UB)
vedi il

Direi che foo(char*a){return*a+1==a[1]?foo(a+1):++*a;}è abbastanza buono; Solo 1 carattere più corto del più naturalefoo(char*a){while(*a+1==a[1])a++;return++*a;}
vedi il

@Il costante comportamento indefinito è considerato accettabile su PPCG
Keyu Gan,

5

Python 3 , 74 62 58 44 40 byte

-12 byte grazie a Erik the Outgolfer. -18 byte grazie a Leaky Nun. -4 byte grazie a musicman523.

Accetta input come bytestring.

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

Provalo online!

Un'altra soluzione interessante:

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

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




1
La tua soluzione è ciò che stavo
cercando,

4

Mathematica, 46 byte

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

Credo che Min@Complement[CharacterRange@@#[[{1,-1}]],#]&salverebbe un byte.
LegionMammal978,

@ LegionMammal978 in realtà 2!
J42161217

3

JavaScript (ES6), 70 byte

Input come una matrice di caratteri

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

Meno golf

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

Test

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 byte

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

Provalo online! Funziona con qualsiasi intervallo di caratteri ASCII. Modifica: salvato 8 byte grazie a @MartinEnder. Spiegazione: Il primo stadio duplica l'input. Il secondo riduce tutti i caratteri nella copia di 1 punto di codice. La terza fase elimina tutti i personaggi nella copia che appaiono ancora nell'originale. Questo lascia solo l'input originale, il carattere che precede il primo carattere dell'input originale e il carattere mancante. L'ultima fase corrisponde quindi solo al personaggio mancante.


Eccone 25, usando la stessa idea di base: tio.run/##K0otycxL/P9fhevQNpV4rpCEgoT4ggQ9LRUulwQ9LsUEPZX///… (sto diminuendo la seconda riga perché salva un byte e poi trovo il carattere univoco usando la deduplicazione.)
Martin Ender,

@MartinEnder La deduplicazione è esattamente quello che volevo da sempre, e ho già dimenticato che Retina ce l'ha, sospiro ... (So che l'incremento della prima riga richiede un byte in più rispetto al decremento della seconda riga ma ha reso la regex più breve).
Neil

3

SWI Prolog, 124 byte

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).

Esempi:

?- 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.

Piccola spiegazione:

La mè la procedura "principale", la nproduce carattere successivo previsto nella lista. Il cconfronto fa: se l'aspettativa corrisponde all'elemento successivo, continua, altrimenti stampa il personaggio previsto e salta fuori dalla finestra.


1
Più breve di fail: 0=1.
mat

3

C ++ 14, libreria standard, tipo contenitore generico ( 87 86 byte)

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

Tipo contenitore dal namespace ::stdpresume (es std::string, std::listo std::vector. Altrimenti using namespace std;o simile sarebbe stata assunta.

Grazie a @Ven, con un po 'di hacking del preprocessore, si arriva a 82 byte (1 nuova riga)

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

Guardalo Live On Coliru

C ++ 14 nessuna libreria standard (ancora generico, 64 63 byte)

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

Ancora una volta, è necessario aiutare la ricerca dei nomi solo se il tipo di contenitore non proviene dallo spazio dei nomi ::std(o ad esso associato)

Live On Coliruper std::stringes

Live On Coliruper char const[]es


Devi inserire uno spazio tra il testo barrato e il testo successivo.
CJ Dennis,

@CJDennis Done. A proposito, il tuo attuale rappresentante (2469) è un numero bellissimo (essendo 3 * 823 e anche visivamente accoppiato come (24) (69) che è (2 2 2 3) (3 23))
vedi il

2

Carbone , 18 byte

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

Provalo online! Il collegamento è alla versione dettagliata del codice. Accetta l'input come stringa. Funziona con qualsiasi sequenza quasi contigua di caratteri ASCII.


2

C #, 104 byte

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

Versione completa / formattata:

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 versione molto intelligente di Linq di Ed'ka :s=>s.Select(e=>++e).Except(s).First()
Charlie

@CarlosAlejo Ho visto che l'hai aggiunto alla tua risposta, quindi non aggiornerò il mio, ma sì, è molto intelligente. Molto più breve della mia versione di farlo.
TheLethalCoder

2

MATL, 8 7 byte

1 byte salvato grazie a @Luis

tdqf)Qc

Provalo su MATL Online

Spiegazione

      % 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 Fantastico, grazie!
Suever,

2

Excel, 110 + 2 = 112 byte

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

Deve essere inserito come una formula di matrice ( Ctrl+ Shift+ Enter) che aggiunge parentesi graffe { }su ciascuna estremità, aggiungendo due byte. L'input è come una stringa in A1, che è OK per OP .

Questa non è di gran lunga la risposta più breve (Excel raramente lo è) ma mi piace vedere se può essere fatto.



2

CJam , 6 byte (programma completo) / 7 byte (blocco di codice)

q),^W=

Provalo online!

Questo è un programma CJam completo che legge la stringa di input dall'input standard e stampa la lettera mancante sull'output standard. CJam in realtà non ha "metodi", che è ciò che la sfida richiede, ma la cosa più vicina sarebbe probabilmente un blocco di codice eseguibile, come questo:

{),^W=}

Provalo online!

Questo blocco di codice, quando valutato, accetta l'input come stringa (ovvero una matrice di caratteri) nello stack e restituisce il carattere mancante anche nello stack.


Spiegazione: Nel programma completo, qlegge la stringa di input e la mette nello stack. )quindi elimina l'ultimo carattere della stringa di input e l'operatore di intervallo ,lo trasforma in un array contenente tutti i caratteri con punti di codice al di sotto di esso (incluse tutte le lettere prima dell'alfabeto). Quindi, per esempio, se l'input fosse cdfgh, allora dopo ),lo stack conterrebbe le stringhe cdfg(cioè l'input con l'ultima lettera rimossa) e ...abcdefg, dove ...sta per un gruppo di caratteri con codici ASCII sotto a(cioè tutti i caratteri sotto l'ultimo input rimosso lettera).

L'operatore di differenza di set simmetrico ^quindi combina queste stringhe in un'unica stringa che contiene esattamente quei caratteri che compaiono in una delle stringhe, ma non in entrambe. Conserva l'ordine in cui i caratteri compaiono nelle stringhe, quindi per l'input di esempio cdfg, il risultato dopo ),^sarà ...abe, dove di ...nuovo sta per un gruppo di caratteri con i codici ASCII sotto a. Infine, W=estrae solo l'ultimo carattere di questa stringa, che è esattamente il carattere mancante eche volevamo trovare (e scarta il resto). Al termine del programma, l'interprete CJam stampa implicitamente il contenuto dello stack.


Bonus: GolfScript , 6 byte (programma completo)

),^-1>

Provalo online!

Si scopre che quasi lo stesso codice funziona anche in GolfScript. Salviamo un byte nella versione completa del programma a causa dell'input implicito di GolfScript, ma perdiamo un byte perché, a differenza di CJam W, GolfScript non ha una comoda variabile a lettera singola inizializzata su -1.

Inoltre, CJam ha tipi interi e di caratteri separati (e le stringhe sono solo array contenenti caratteri), mentre GolfScript ha solo un tipo intero (e ha un tipo di stringa speciale che si comporta in modo leggermente diverso dagli array normali). Il risultato di tutto ciò è che, se vogliamo che l'interprete GolfScript stampi la lettera mancante effettiva anziché il suo numero di codice ASCII, dobbiamo restituire una stringa a carattere singolo anziché solo il carattere stesso. Fortunatamente, apportare questa modifica qui richiede solo la sostituzione dell'operatore di indicizzazione =con l'operatore di troncamento sinistro array / stringa >.

Naturalmente, grazie all'I / O implicito di GolfScript, il codice sopra può essere utilizzato anche come frammento che legge una stringa dallo stack e restituisce una stringa di un carattere contenente la lettera mancante. O, piuttosto, qualsiasi frammento che accetta una singola stringa nello stack come argomento e restituisce il suo output come stringa stampabile nello stack, è anche un programma GolfScript completo.


6
Gli snippet di codice non sono consentiti per impostazione predefinita ; sono solo funzioni e programmi completi. Quindi probabilmente hai bisogno di quel q(programma) o {...}(blocco). +1 per l'approccio però
Luis Mendo,

Questo è molto intelligente!
Esolanging Fruit,

2

Buccia , 6 byte

→S-(ḣ→

Provalo online!

Questa funzione accetta una stringa (elenco di caratteri) come input e restituisce un carattere come output.

Spiegazione

→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 byte

Perde la soluzione esistente di Python 2 ma è un approccio leggermente diverso, quindi ho pensato di pubblicarlo comunque:

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

2

8 ° , 99 byte

Fondamento logico

Se la distanza tra le lettere è maggiore di due, allora c'è una lettera mancante. La distanza tra le lettere si ottiene calcolando la differenza tra il codice ASCII di ciascuna lettera.

Codice

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

Versione Ungolfed

: 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
;

Utilizzo ed esempi

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 byte

Accetta l'input come stringa.

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

Come?

  • Inizializzazione: iniziamo con n = 0 e p = 0 e chiamiamo la funzione ricorsiva 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
  • Passaggio n. 1: incrementiamo n fino a quando c = String.fromCharCode(n)è uguale al primo carattere della stringa di input s [0] .

  • Passaggio 2: ora che siamo sincronizzati, incrementiamo contemporaneamente n e p fino a quando c = String.fromCharCode(n)non è più uguale a s [p] .

  • Step # 3: Restituiamo c : il personaggio previsto che non è stato trovato.

Casi test


1

J, 20 byte

{&a.>:I.1 0 1&E.a.e.
  • a.e. maschera booleana per le lettere di input nel set di caratteri ASCII
  • 1 0 1&E.nuova maschera booleana che indica se la sequenza 101inizia in quell'indice, cioè trova un punto in cui inizia una sequenza "salta"
  • I. l'indice di quella partita, cioè il personaggio prima di quello saltato
  • >: incrementare di 1, cioè l'indice del carattere ignorato all'interno del set di caratteri ascii
  • {&a. scegli quell'indice dal set di caratteri ascii, cioè restituisce il carattere saltato

Provalo online!


A me sembra uno snippet.
Adám,

@Adám È scritto in uno stile tacito (privo di punti), che a mio avviso conta come "funzionale" in contrapposizione a uno snippet. Per quanto posso dire, non è più un frammento di quanto sia la tua soluzione APL (ma non conosco il dyalog, quindi prendi quello che dico con un granello di sale).
zgrep,

@ Adám sì, nel senso che non può essere assegnato a una variabile ma assume input sul lato destro. non è legale? l'ho chiesto da qualche parte e mi è stato detto che andava bene
Giona,

La mia comprensione per APL / J / K è che il codice deve essere in grado di risiedere in un nome, sia per incarico o come corpo un verbo / funzione esplicita (tuttavia, anche il modulo esplicito deve avere un input esplicito). Lo snippet è un codice che assume valori nelle variabili e / o deve essere incollato in una riga, ma non può essere autonomo.
Adám,

@zgrep No, questo codice è esplicito (non tacito), ma manca il riferimento al suo argomento all'estrema destra. La mia funzione APL è una funzione tacita completa che può essere assegnata o inserita tra parentesi.
Adám,

1

ES6, 125 byte:

(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 funzione restituita deve essere chiamata con un array

(["a","c"])

si potrebbero salvare altri 9 byte rimuovendo .join ("") e passando una stringa:

("ac")

ES6, 108 byte:

(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
legare ??? nel codice golf?
edc65,

@ edc65 cosa c'è che non va? (scusate se questo è n00b, ma questo è il mio primo golf :))
Jonas Wilms,

@ edc65 ma probabilmente hai ragione, rimuovendolo salvato 4 byte ...
Jonas Wilms

a.join("")potrebbe esserea.join``
user2428118,

1

Lisp comune, 88 byte

(lambda(s)(loop as(x y)on s if(>(#1=char-code y)(1+(#1#x)))return(code-char(1+(#1#x)))))

Provalo online!


1

Python 2 , 69 byte

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

Provalo online!

Alcune spiegazioni Poiché conosciamo il primo e l'ultimo elemento dell'elenco, possiamo facilmente calcolare la somma dei codici di tutti i caratteri nel list + the missed char(usando le formule di riepilogo della progressione aritmetica ). La differenza tra questa somma e la somma dei codici di tutti i caratteri nel listdà il codice della lettera mancata.



1

APL (Dyalog) , 17 byte

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

Provalo online!

⎕AV∘∊ Booleano: ogni personaggio nel membro A tomic V ector (set di caratteri) dell'argomento?

(... ) applica la seguente funzione tacita:

 il primo elemento di

⎕AV the A tomic V ector (il set di caratteri)

/⍨ quale

∨\ segue l'iniziale (membro dell'argomento)

 ma

~ non è (un membro dell'argomento)

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.