È un sostantivo o no?


22

Data una stringa come input, determina se è un sostantivo o no.

Sarai segnato sulle 1000 parole inglesi più comuni, da quante etichetta correttamente come un nome o no.

Vincerà il programma o la funzione che classifica correttamente la maggior parte di quelle parole in 50 byte o meno.

I sostantivi

Un sostantivo è una parola che rappresenta una cosa, in genere. Diventa più complesso, ma questa è l'idea di base.

Nei casi in cui una parola potrebbe essere un sostantivo o un'altra parte del discorso, l'ho classificata come un sostantivo, anche se è un uso raro. O in realtà, ho lasciato questo sito per me.

Le parole su cui verrai segnato sono queste 1000 parole comuni , che provengono dalla semplice Wikipedia , con "due" e "una volta" aggiunte. Di questi, questi sono i 586 sostantivi e questi sono i 414 non sostantivi . Puoi trovare tutte e tre le liste qui . Si noti che tutti questi ingressi sono in minuscolo. Questi elenchi sono definitivi: non tentare di discutere di grammatica.

Il tuo programma sarà considerato corretto se genera un risultato di verità su un input che è un sostantivo e un risultato di falsa su un input che non è un sostantivo.

sottigliezze:

I programmi devono avere un output deterministico. Se vuoi usare la casualità, semina. I programmi non sono autorizzati a utilizzare elenchi di nomi incorporati o altre funzionalità di sintesi vocale incorporate.

Esempi:

a: noun
act: noun
active: noun
about: non-noun
above: non-noun
across: non-noun

Indica la percentuale di successo del tuo programma nella tua risposta. Vince il programma o la funzione di massimo 50 byte con il più alto tasso di successo. In caso di pareggio, il numero di byte più basso determinerà un vincitore. In bocca al lupo!

Risposte:


13

JavaScript (ES6), 43 byte, 622 630 633

Solo per far rotolare la palla. Restituisce 1per i nomi, 0per i non nomi.

s=>2552>>s.length&/^[bcdf-mp-tvwy]/.test(s)

Come?

Scommettiamo sul nome se sono soddisfatte entrambe le seguenti condizioni:

  1. La lunghezza della parola è 3, 4, 5, 6, 7, 8 o 11. Questo viene fatto spostando a destra il numero binario 100111111000 (2552 come decimale).
  2. La parola inizia con una di queste lettere: bcdfghijklmpqrstvwy

Proprio mentre stavo per commentare, tenendo conto in particolare di JS, che il limite di byte era troppo restrittivo, pubblichi questo! Stavo pensando, senza aver guardato l'elenco, che un punteggio migliore di 586 potrebbe essere possibile solo testando la prima lettera o 2 in ogni parola. Ben fatto :)
Shaggy,

Una spiegazione sarebbe utile per le persone che non hanno familiarità con Javascript. Per quanto ne so, questo controlla se la lunghezza della parola è 3, 4, 5, 6, 7, 8 o 11 e la parola inizia anche con una di una serie di lettere?
isaacg,

@isaacg È corretto. Spiegazione aggiunta.
Arnauld,

4
Nota che la classe di caratteri [bcdf-mp-tvwy]è equivalente alla classe [^aenouxz]. Una modifica risparmierebbe 4 byte, che potrebbero essere capitalizzati.
fireflame241

@ fireflame241 Molto vero. E questo può anche essere abbreviato [^aenouz]perché non abbiamo alcuna parola che inizia con a x.
Arnauld,

11

Gelatina , 48 byte, punteggio 731

Questa è la mia prima risposta in assoluto in Jelly e ho avuto molti problemi a metterlo insieme. Ah bene ... è stato divertente. :-)

O‘ḅ⁹%⁽€Oæ»4“Ạ$ⱮẊḲḲLÑMṆụ⁻ẉṂ`ŻvḤæɠ5ṭȯƁU*×TdƲḥ`’æ»Ḃ

1 byte salvato grazie a @JonathanAllan

Provalo online!

Guasti e test suite

  • Non nomi correttamente identificati come non nomi: 265/414 (64%)
  • Sostantivi identificati correttamente come sostantivi: 466/586 (79,5%)

Come?

Per prima cosa calcoliamo un hash della stringa di input:

  • convertendolo in un numero intero interpretando ogni punto di codice come una cifra di base 256
  • applicando modulo 4080 (scelto come valore più efficiente con non più di 12 bit)
  • mantenendo gli 8 bit più significativi del risultato

Questo ci lascia con un indice in [0 ... 255] e quindi divide tutte le parole in 256 gruppi.

Per ogni gruppo di parole, pre-calcoliamo un flag binario che è 1se il gruppo contiene più nomi di non nomi, e 0altrimenti. Questo porta a un numero N a 256 bit che useremo come tabella di ricerca. Lo memorizziamo come una stringa codificata in base 250.

Sotto è la rappresentazione binaria di N .

1000011000001011000101111011111001001101110010101101110010001101
0000010001101010010111110001110010010101110110110010111111010000
0001111010011110000110101011111000011110111011010011011110101100
1010010110101111000010101000101100000001110110100011111000101010

Che può essere memorizzato come “Ạ$ⱮẊḲḲLÑMṆụ⁻ẉṂ`ŻvḤæɠ5ṭȯƁU*×TdƲḥ`’in Jelly.

Da qui il codice:

O‘ḅ⁹%⁽€Oæ»4“Ạ$ⱮẊḲḲLÑMṆụ⁻ẉṂ`ŻvḤæɠ5ṭȯƁU*×TdƲḥ`’æ»Ḃ    main link

O                                                   convert the input string to a list of
                                                    code points
 ‘                                                  increment each of them
  ḅ⁹                                                convert from base 256 to an integer
    %⁽€O                                            modulo 4080
        æ»4                                         drop the 4 least significant bits
           “Ạ$ⱮẊḲḲLÑMṆụ⁻ẉṂ`ŻvḤæɠ5ṭȯƁU*×TdƲḥ`’æ»     right shift N by this amount
                                               Ḃ    test the least significant bit

Bel lavoro! Salva un byte con cui avviare O‘ḅ⁹%⁽€Oæ»4“Ạ$ⱮẊḲḲLÑMṆụ⁻ẉṂ`ŻvḤæɠ5ṭȯƁU*×TdƲḥ`’æ»Ḃ(nota anche che puoi usare il piè di pagina su TIO, andrei con Ç€¬S,Le Ç€S,Lper le tue due suite di test.
Jonathan Allan,

@JonathanAllan Grazie per i suggerimenti!
Arnauld,

10

JavaScript (ES6), 50 byte, punteggio 693

s=>!/^([aouz]|th|..$)|e.+[ey]|[flo].r|a.p/.test(s)

Sto solo cercando i possibili schemi che i non sostantivi hanno che i sostantivi no.

I non nomi più spesso contengono:

  1. a, o, u o z come prima lettera.
  2. th come le prime due lettere.
  3. Solo due lettere. [Pensa ai pronomi (io, noi, noi, lui, esso) e alle preposizioni (di, a, in, su, da, a, su, ...).]
  4. e , seguito da una o più lettere, seguito da e o y .
  5. f, l, o o , seguito da qualsiasi lettera, seguita da r .
  6. a , seguito da qualsiasi lettera, seguito da p .

Frammento:


Credo che puoi salvare un byte modificando il primo regex in /h|n/(o facendo /^.[hn]/.test(s)) e un altro cambiando s[2]>''in uno !!s[2]o 2 in s.
ETHproductions

Grazie, @ETHproductions. Posso usare i tuoi suggerimenti e combinare i due test per salvare un mucchio di byte, che mi ha permesso di aggiungere codice per migliorare il mio punteggio.
Rick Hitchcock,

Non è a.pridondante poiché lo hai già fatto [aouz]?
AdmBorkBork,

@AdmBorkBork, a in [aouz]viene confrontato solo all'inizio della stringa. Per qualsiasi motivo, testare in a.p qualsiasi punto della stringa migliora il punteggio.
Rick Hitchcock,

10

Gelatina , 50 byte , punteggio 763

Usando un hash ora (proprio come la risposta della gelatina di Arnauld )

OP%⁽Wpị“!ḋGẠ⁻Ṭȥʋt|Ḥ\⁾°½İ@G2ḂƑ½ịʂ¶ɦḲ⁷³Hz~⁵p9)⁹ƙ¿’B¤

Provalo online!

250/414 per i non sostantivi
513/586 per i nomi
totali = 250 + 513 = 763.

Come?

Crea una tabella con 308 voci, 1 (identificando un sostantivo) o 0 (identificando un non sostantivo) e indicizza in essa una chiave fornita da una funzione hash che utilizza il prodotto degli ordinali della parola di input:

OP%⁽Wpị“!ḋGẠ⁻Ṭȥʋt|Ḥ\⁾°½İ@G2ḂƑ½ịʂ¶ɦḲ⁷³Hz~⁵p9)⁹ƙ¿’B¤ - Link: list of characters, word
O                                                  - convert to ordinals
 P                                                 - product
   ⁽Wp                                             - base 250 number = 22863
  %                                                - modulo (by 22863)
                                                 ¤ - nilad plus link(s) as a nilad:
       “!ḋGẠ⁻Ṭȥʋt|Ḥ\⁾°½İ@G2ḂƑ½ịʂ¶ɦḲ⁷³Hz~⁵p9)⁹ƙ¿’   -   base 250 number
                                                B  -   as a binary list (308 bits)
      ị                                            - index into (1-indexed and modular,
                                                  -   so adds another modulo by 308)

Precedente:  50  47 byte , punteggio 684

ḣ3Ẇf“QṘ°ḂżÐŒ#ḍæ09»s2¤Ȧ¬ȧØY⁾niyṖf⁽ż2ị$
0,-2ịE¬ȧÇ

Un collegamento monadico che prende una parola e restituisce un elenco di un carattere (verità) se la parola viene identificata come un nome, o una lista vuota o zero (entrambe false) se non lo è.

Provalo online! (il piè di pagina esegue un if if sul risultato da stampareNounoNon-Noun)
... o visualizza il programma di punteggio (conta gli indici di verità tra le due liste e quindi calcola il punteggio).

Ripartizione del punteggio: 462/586 nomi identificati correttamente (124 inesatti), 222/414 nomi non identificati correttamente (192 inesatti) - totale corretto = 684/1000.

Come?

Immagino che non sia un sostantivo se ...

  • l'ultimo carattere e il carattere due precedenti sono uguali (con indicizzazione modulare e basata su 1)
  • una delle prime due sottostringhe di lunghezza 2 è in:
    'be', 'th', 'le', 'he', 'm ', 'ev', 'et', 's ', 'fl', 'ax', 'en', 'fo', 'am', 'az' (nota: 'm 'e 's 'sono qui solo per facilitare la compressione, ma non appaiono mai comunque)
  • L' indice -299 ° (con indicizzazione modulare e basata su 1) è uno dei seguenti:
    aenouyz(sebbene questo sia implementato inversamente e con lettere maiuscole in eccesso)
    ... poiché le parole hanno tutte una lunghezza compresa tra 1 e 11, l' indice -299 ° è equivalente all'utilizzo della lunghezza per indicizzare il mapping:{7:2; 8:5; 9:7; 11:9; else 1}

ḣ3Ẇf“QṘ°ḂżÐŒ#ḍæ09»s2¤Ȧ¬ȧØY⁾niyṖf⁽ż2ị$ - Link 1: list of characters, word
ḣ3                                    - head to index 3 (1st 3 characters, like 'abc')
  Ẇ                                   - all sublists (['a','b','c','ab','bc','abc']
                    ¤                 - nilad followed by link(s) as a nilad:
    “QṘ°ḂżÐŒ#ḍæ09»                    - compression of "bethlehem evets flaxenfoamaz"
                  s2                  - split into chunks of 2:
                                      -   be,th,le,he,m ,ev,et,s ,fl,ax,en,fo,am,az
   f                                  - filter keep (can only match 'ab' or 'bc')
                     Ȧ                - any and all (0 if empty, 1 if not)
                      ¬               - logical not
                        ØY            - consonant -y yield = "BCD...WXZbcd...wxz"
                          ⁾ni         - character pair = "ni" (no shrubbery for you!)
                             y        - translate (exchange the n for an i)
                              Ṗ       - pop (remove the z)
                       ȧ              - logical and
                                    $ - last two links as a monad:
                                ⁽ż2   -   base 250 literal = -299
                                   ị  -   index into the word
                               f      - filter keep

0,-2ịE¬ȧÇ - Main link: list of characters, word
0,-2      - pair zero with -2 = [0,-2]
    ị     - index into the word (last character and the one before the one before that)
     E    - all (both) equal?
      ¬   - logical not
        Ç - call the last link (1) as a monad
       ȧ  - logical and

13 byte, punteggio: 638

Una prima rapida bash (estesa sopra)

ØY⁾niyṖf⁽ż2ị$

0,-2non significa pair zero with -2che significhiliteral [0, -2]
Erik the Outgolfer,

Ma è lo stesso effetto: p
Jonathan Allan,

no, non 0,-2è un nilad, non separato (0)(,)(-2)... ovviamente è lo stesso effetto in questo caso, ma non sempre. L'ho imparato nel modo più duro ... e in ogni caso preferirei comunque spiegare cosa succede effettivamente invece di qualcosa con lo stesso effetto o qualcosa.
Erik the Outgolfer

Se avessi scritto "join" anziché "pair" avresti commentato "nessun join è j"?
Jonathan Allan,

Potrei essere un po 'pedante, ma pairo joinsono ovviamente modi sbagliati di esprimerlo, poiché 0,-2,-6ad esempio non significa pair 0 with -2 and then pair that with -6 = [[0, -2], -6]ma piuttosto significa literal [0, -2, -6]. Capisco, l' , atomo e il ...,...(,...(...)) letterale sono confusi ... ma stilll 0,-2,-6non è più lo stesso di 0,-2;-6quando il primo è 1 link e il secondo è 3 link.
Erik the Outgolfer,

2

Julia 34bytes, 609

f(w)=hash(w)&0x0800000000004808>0

Volevo risparmiare sui personaggi usando l'hash incorporato. Sento che ci deve essere un modo per farlo meglio. Julia non è abbastanza amichevole con le operazioni di bit banging che voglio usare per renderlo migliore, penso.

Trovare maschere di bit adatte per l'hash per separarle, è un gioco interessante.


Migliore soluzione;)
tamasgal

2

Python 2 , 50 byte, precisione: 596

lambda x:2<len(x)<7 or x[0]in"abcgmprs"or"st" in x

Provalo online!

Controlla semplicemente la prima lettera, la lunghezza e se "st" è nella parola Il codice presuppone che la parola sia definita come x (Modifica: grazie a issacg per aver corretto il codice dallo snippet alla funzione)


Ciao, benvenuto nel sito. Anche se questo è interessante, gli invii sono tenuti a essere fuction o programmi completi. Questo è un frammento, che non è consentito. Guarda questo Provalo online! link per un modo per convertire questo frammento in una funzione mentre si esegue ancora lo stesso codice.
isaacg,

2

Haskell, 36 byte, 626 631

f x=length x>2&&x!!0`notElem`"aenou"

643 se qualcuno ha una lingua più breve:length x>2&&(x!!0`notElem`"aenou"||x!!1`elem`"acqrsty")
BlackCap

2

Implementazione della porta logica a 2 livelli, non 50 byte, punteggio 1000

  1. Basta collegare la rappresentazione binaria della parola data agli 88 ingressi

    1. completare la parola di input con spazi a destra se la lunghezza della parola è inferiore a 11
    2. Codice ASCII a 8 bit per ogni lettera della parola di input
  2. Il circuito restituisce 1 se la parola è un sostantivo e restituisce 0 in caso contrario

  3. Le linee tratteggiate blu sono per input mai usati

Questa implementazione ha bisogno

  1. 48 transistor per codificare tutte le porte degli inverter
  2. 1100 transistor per codificare tutte le porte AND
  3. 154 transistor per codificare la porta OR
  4. Totale di 1302 transistor che rappresentano meno di 28 byte.

Alcune misure

  1. Una porta dell'inverter necessita di 1 transistor
  2. Una porta OR semplice a 2 ingressi richiede 2 transistor
  3. Una porta AND semplice a 2 ingressi richiede 2 transistor
  4. Un bit ha bisogno di 6 transistor

inserisci qui la descrizione dell'immagine

Risoluzione completa Circuit.pdf qui

Risoluzione completa Circuit.png qui


2
Potresti spiegare esattamente qual è il tuo sistema per codificare questo circuito in byte? Sono molto confuso su come affermi di usare 28 * 8/1302 = 0,17 bit per transistor.
isaacg,

Poiché la mia soluzione è una soluzione informatica di livello molto basso (hardware anziché software), ho basato il mio byte contando su transistor. Per quanto riguarda l'hardware, un BIT è codificato da 6 transistor, quindi possiamo supporre che un transistor rappresenti 1/6 bit (circa 0,17).
mdahmoune,

1
Capisco il tuo punto di vista, tuttavia l'origine del codice di 50 byte deve esistere da qualche parte su un hardware concreto (transistor in genere)
mdahmoune

1
Non è solo un punto di vista, è un requisito della sfida. Contrassegna la tua risposta come non competitiva, poiché non soddisfa i requisiti per competere su questa sfida.
isaacg,

2
Una semplice codifica binaria non compressa delle informazioni richieste per ricreare questa soluzione potrebbe utilizzare 2 bit per il tipo di ciascuna porta logica (3 porte diverse) e 10 bit per ciascun indirizzo di ingresso e uscita di ciascuna porta logica (675 porte più ingressi e uscite). 2 * (48 + 550 + 77) + 10 * (2 * 48 + 3 * (550 + 77)) = 21120 bit = 2640 byte.
Nnnes,

1

Python 3, 50 byte, punteggio 602

Python non è il linguaggio più dettagliato, ma 50 byte è difficile.

lambda x:all(x.count(y)<1for y in["ful","y","er"])
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.