Quante sillabe in quel numero?


15

Mi piacerebbe prendere un numero e sapere quante sillabe ci sono, quando si parla in inglese.

Limitiamolo a numeri interi positivi che sono meno di mille.

Sono britannico, quindi seguiremo la colonna delle centinaia con un 'e' quando ci saranno cifre diverse da zero dopo di essa.

La sfida

  • Scrivi un codice che accetti un numero intero positivo inferiore a 1000 e produca il numero di sillabe nelle parole che rappresentano quel numero in inglese britannico.
  • NON è necessario generare le parole per rappresentare i numeri, solo il numero di sillabe che contengono.
  • È il golf del codice, cerca di raggiungere questo risultato nel minor numero di byte.
  • Usa la lingua che preferisci.
  • Le scappatoie standard sono vietate.

Casi test

|  N  | In words                             | Syllables |
|   1 | one                                  |         1 |
|   2 | two                                  |         1 |
|   3 | three                                |         1 |
|   4 | four                                 |         1 |
|   5 | five                                 |         1 |
|   6 | six                                  |         1 |
|   7 | sev-en                               |         2 |
|   8 | eight                                |         1 |
|   9 | nine                                 |         1 |
|  10 | ten                                  |         1 |
|  11 | el-ev-en                             |         3 |
|  12 | twelve                               |         1 |
|  13 | thir-teen                            |         2 |
|  14 | four-teen                            |         2 |
|  17 | se-ven-teen                          |         3 |
|  20 | twen-ty                              |         2 |
|  21 | twen-ty one                          |         3 |
|  42 | four-ty two                          |         3 |
|  73 | sev-en-ty three                      |         4 |
|  77 | sev-en-ty sev-en                     |         5 |
| 100 | one hund-red                         |         3 |
| 110 | one hund-red and ten                 |         5 |
| 111 | one hund-red and el-ev-en            |         7 |
| 555 | five hund-red and fif-ty five        |         7 |
| 700 | sev-en hund-red                      |         4 |
| 770 | sev-en hund-red and sev-en-ty        |         8 |
| 777 | sev-en hund-red and sev-en-ty sev-en |        10 |
| 999 | nine hund-red and nine-ty nine       |         7 |

1
Possiamo prendere l'input come una stringa o una matrice di cifre?
Dennis,

Risposte:


11

Python 2 , 84 83 74 67 byte

lambda n:4*(n>99)+2-n%~9/9-0x55561aaaab/4**(n%100)%4+`n`.count('7')

Grazie a @xnor per giocare a golf con 9 16 byte!

Provalo online!


Python 2 , 79 byte

lambda n:4*(n>99)+([-1]+10*[1]+[3,1]+7*[2]+8*([2]+9*[3]))[n%100]+`n`.count('7')

Semplice, ma più lungo.

Provalo online!


Per la soluzione di 83 byte, è possibile tagliare 3 byte cambiando -10ad ~9e il passaggio attorno l'ultimo bit a +(0<n%100!=12)-(n%100!=11), ma questo è ancora più a lungo la vostra nuova soluzione.
xnor


@xnor È davvero intelligente! min(n%100,13)%12/~9potrebbe effettivamente aiutare con un approccio che stavo cercando anche per la mia risposta Jelly.
Dennis,

In realtà, solo spingere le cose in una costante codificata risulta più breve.
xnor

@xnor Grazie ancora!
Dennis,

8

Perl 5 -p , 53 byte

$_=4*/.../+2*/[^0].$/+!/0$/+y/7//-/1[^1]$/-/12$/-/00/

Provalo online!

Come

-p commandline flag reads input into $_

$_=4*/.../     # Hundreds place has minimum of 4 sylables (__ HUN-DRED AND),
               # match fails on number <100, and would add 0 here
  +2*/[^0].$/  # Tens place has two syllables if not 0 (__-TY or __TEEN),
               # match fails on numbers <10, and would add 0
  +!/0$/       # Ones place has one syllable if not 0 (__)
               # -- Now adjust for special cases --
  +y/7//       # add a syllable for every 7 present
  -/1[^1]$/    # remove a syllable for 10-19, except 11
  -/12$/       # remove another syllable for 12
  -/00/        # remove the syllable for AND if it's an even hundred

-p commandline flag outputs contents of $_

7

JavaScript (ES6), 89 byte

n=>(s='01111112111312222322',n>99&&+s[n/100|0]+3-!(n%=100))+~~(s[n]||+s[n/10|0]-~s[n%10])

Provalo online!


7

Python 2 , 112 108 byte

f=lambda n:n>99and f(n/100)+3+f(n%100)-(n%100<1)or n>19and f(n/10)-~f(n%10)or int("01111112111312222322"[n])

Provalo online!

-4 byte, grazie a Shaggy


2
Inoltre, la tua [2]*7parte fallirà 17, poiché dovrebbe essere 3 anziché 2 ( sev-en-teen).
Kevin Cruijssen,

2
-4 byte , inclusa una correzione per 17.
Shaggy

@Shaggy Thanks :)
TFeld il

@KevinCruijssen Risolto ora (grazie a Shaggy)
TFeld il


6

Lingua Wolfram 101 115 byte

s=StringSplit;Length[Join@@(WordData[#,"Hyphenation"]&/@Join@@s/@
s[IntegerName@#,"-"])]+Boole[#>100&&#~Mod~100!=0]&

Spiegazione

(in sostituzione StringSplitdi s)

Length[Join@@(WordData[#,"Hyphenation"]&/@Join@@
StringSplit/@ StringSplit[IntegerName@#,"-"])]+Boole[#>100&&#~Mod~100!=0]&

IntegerName rende il numero in inglese americano (ovvero senza "e" incluso in numeri maggiori di 100.) Ad es 777-> "seven hundred seventy-seven .

StringSplit[IntegerName@#,"-"] rimuove i trattini nel rendering.

StringSplit/@ divide il rendering in parole.

Join@@ lascia un semplice elenco di parole, senza elenco incorporato (nel caso in cui apparisse un trattino).

WordData[#,"Hyphenation"] spezza una sola parola nelle sue sillabe.

Join@@ lascia un semplice elenco di sillabe in tutte le parole.

Length conta le sillabe

+Boole[#>100&&#~Mod~100!=0]aggiunge 1al conteggio delle sillabe per quei numeri maggiori di 100 (a causa dell'ulteriore "e" impiegato nel rendering inglese britannico), esclusi i multipli integrali di 100.


6

Java 11, 105 102 byte

n->(""+"".repeat(8)).charAt(n%100)+(n+"").split("7",9).length-(n>99?2:6)

Contiene un sacco di caratteri non stampabili.

-3 byte grazie @ OlivierGrégoire .

Provalo online.

Spiegazione:


n->               // Method with integer as both parameter and return-type
  (""
                  //  Push string with ASCII-value digits 46666666666867777777
 +"".repeat(8))
                  //  Appended with 8 times a string with ASCII-value digits 7888888888
   .charAt(n%100) //  Take the (input modulo-100)'th character of this string (as integer)
  +(n+"").split("7",9).length
                  //  Count the amount of 7s in the input + 1
  -(n>99?         //  And if the input is larger than 99:
     2            //   Subtract 2 (-1 for the 7s+1 count; -5 to map the ASCII-digits to:
                  //               4 → -1; 6 → 1; 7 → 2; 8 → 3;
                  //               and +4 for the inputs above 99)
    :             //  Else:
     6)           //   Subtract 6 (-1 for the 7s+1 count and -5 to map the ASCII-digits to:
                  //               4 → -1; 6 → 1; 7 → 2; 8 → 3)

1
102 byte cambiando .split("7",-1)in .split("7",9)e -6+(n>99?4:0)in -(n>99?2:6).
Olivier Grégoire,

1
@ OlivierGrégoire Grazie. Completamente mancato -(n>99?2:6), ma è così ovvio ora che l'hai sottolineato. E -1a 9causa delle dimensioni di input limitate non avrei pensato, quindi grazie!
Kevin Cruijssen,

5

05AB1E , 34 31 byte

т%U7¢I€Ā`Iт@3*X_(X20@X12Q(X11QO

Provalo online o verifica tutti [1,999]i casi di test .

Spiegazione:

Con tutti i controlli menzionati, il risultato sarà 1 per verità e 0 per falsità.

т%         # Take modulo-100 of the (implicit) input
           #  i.e. 710 → 10
  U        # Pop and store it in variable `X`
7¢         # Count the amount of 7s in the (implicit) input
           #  i.e. 710 → 1
I€Ā        # Trutify each digit in the input (0 if 0; 1 otherwise)
   `       # And push all of the mapped values to the stack
           #  i.e. 710 → [1,1,0]
Iт@        # Check if the input is larger than or equal to 100
           #  i.e. 710 → 1 (truthy)
   3*      # Multiply that result by 3 (for 'hund-red and')
           #  i.e. 1 → 3
X_         # Check if variable `X` is 0
           #  i.e. 10 → 0 (falsey)
  (        # And negate that (to remove 'and' when #00)
           #  i.e. 0 → 0
X20@       # Check if variable `X` is larger than or equal to 20 (for '-ty')
           #  i.e. 10 → 0 (falsey)
X12Q       # Check if variable `X` is exactly 12
           #  i.e. 10 → 0 (falsey)
    (      # And negate that (to remove 'teen')
           #  i.e. 0 → 0
X11Q       # Check if variable `X` is exactly 11 (for 'el-ev-en' minus 'one one')
           #  i.e. 10 → 0 (falsey)
O          # Sum everything on the stack (and output implicitly)
           #  i.e. [1,1,1,0,3,0,0,0,0] → 6

Questo fallisce il test case 700. 'Seven Hundred' ha 4 sillabe, questo restituisce 5.
AJFaraday

@AJFaraday Ora dovrebbe essere risolto. Accidentalmente aveva I(input) invece di X(input mod 100) quando controlla se è maggiore di 20 per il +1 di ty.
Kevin Cruijssen,

Mi dispiace così tanto, restituisce 0 per "cento"
AJFaraday,

@AJFaraday Risolto di nuovo .. >(controlla se l'ingresso è maggiore di 100) è stato sostituito con @(controlla se l'ingresso è maggiore o uguale a 100). Forse avrei dovuto controllare personalmente alcuni altri casi di test prima di pubblicare .. Mi dispiace per quello ..
Kevin Cruijssen,

4
A proposito, amando il cappello a cilindro su un cubo di rubix!
AJFaraday,

5

Carbone , 39 31 byte

I⁻⁺↨E謬Iι²№θ7I§⁺”)∨∧⌈a¡↶”×0⁸⁰N

Provalo online! Il collegamento è alla versione dettagliata del codice. Spiegazione:

I⁻⁺

Calcola le regolazioni del numero di sillabe e genera il risultato come una stringa.

↨E謬Iι²

Inizia cambiando ogni cifra diversa da zero in 1 e poi decodificandola come base 2. Ciò fornisce la risposta corretta per la maggior parte degli input.

№θ7

Aggiungi 1 per ciascuno 7.

I§⁺”)∨∧⌈a¡↶”×0⁸⁰N

Prendi la stringa letterale 10000000001021111111e aggiungi 80 zeri, quindi indicizza ciclicamente l'input e sottrai quella cifra.


4

Gelatina , 28 25 23 byte

9ḊŻ;2+⁵Żċ%ȷ2$ạDṠḄƊ+Dċ7Ɗ

Provalo online!

Come funziona

9ḊŻ;2+⁵Żċ%ȷ2$ạDṠḄƊ+Dċ7Ɗ  Main link. Argument: n (integer in [1, ..., 999])

9                        Set the return value to 9.
 Ḋ                       Dequeue; yield [2, 3, 4, 5, 6, 7, 8, 9].
  Ż                      Zero; yield [0, 2, 3, 4, 5, 6, 7, 8, 9].
   ;2                    Concat 2, yield [0, 2, 3, 4, 5, 6, 7, 8, 9, 2].
     +⁵                  Add 10; yield [10, 12, 13, 14, 15, 16, 17, 18, 19, 12].
       Ż                 Zero; yield [0, 10, 12, 13, 14, 15, 16, 17, 18, 19, 12].
         %ȷ2$            Yield n % 1e2.
        ċ                Count the occurrences of the modulus in the array.
                 Ɗ       Combine the three links to the left into a monadic chain.
              D            Decimal; convert n to its array of digits in base 10.
               Ṡ             Take the sign of each decimal digit (0 or 1).
                Ḅ            Convert the array of signs from base 2 to integer.
             ạ           Compute the abs. difference of the results to both sides.
                      Ɗ  Combine the three links to the left into a monadic chain.
                   D       Decimal; convert n to its array of digits in base 10.
                    ċ7     Count the number of 7's.

3

PHP , 190 158 145 141 137 byte

<?for($j=$p=0;$p<strlen($i=$argv[1]);)$j+=str_split($i)[$p++]>0;echo$j+substr_count($i,7)+3*($i>99)-!($i%=100)+($i>19)-($i==12)+($i==11);

Provalo online!

Un port della soluzione di Kevin Cruijssen (purtroppo non ha la stessa brevità in PHP :))

- 32 45 grazie a Shaggy!

-3 grazie a Kevin Crujissen!


Così tanti risparmi da fare qui! Eccone solo alcuni molto veloci
Shaggy il

1
145 byte . Puoi salvare qualche altro byte usando tag brevi ma non ricordo come usarli su TIO. (Nota: sono sul mio telefono, quindi non ho testato tutti gli ingressi.)
Shaggy,

1
@Shaggy È possibile modificare altri 2 byte quando si utilizza >99e >19invece di >=100e >=20.
Kevin Cruijssen,

1
@KevinCruijssen che in realtà salva 3 byte perché va da 100 a 99 :)
NK1406

Sono anche riuscito a salvare un altro byte posizionando la variabile all'inizio dell'eco.
NK1406,

2

05AB1E , 24 byte

La gelatina di Port of Dennis risponde

8L>Ć¾šT+¾šsт%¢sSĀJCαs7¢+

Provalo online! o come una suite di test

Spiegazione

8L>                       # push range [2 ... 9]
   Ć                      # enclose, append head
    ¾š                    # prepend 0
      T+                  # add 10 to each
        ¾š                # prepend 0
          sт%¢            # count occurrences of input % 100 in this list
              sS          # push input split into a list of digits
                Ā         # truthify, check each if greater than 0
                 JC       # convert from base-2 to base-10
                   α      # absolute difference
                    s7¢+  # add the amount of 7's in the input

1

05AB1E , 26 byte

€ĀJCI7¢•Ž¢Γ}Þ±6u•¾80׫Iè(O

La risposta di Port of @Neil Charcoal , quindi assicurati di votare anche lui se ti piace questa risposta!

Provalo online o verifica tutti i casi di test .

In •Ž¢Γ}Þ±6u•alternativa, il numero intero compresso può essere •8JA•b2TÌǝper lo stesso conteggio byte.

Spiegazione:

€Ā                   # Trutify every digit in the (implicit) input
                     # (0 remains 0; everything else becomes 1)
  J                  # Join it together to a single string
   C                 # Convert from binary to integer
I7¢                  # Count the amount of 7s in the input
•Ž¢Γ}Þ±6u           # Push compressed integer 10000000001021111111
          ¾80׫      # Append 80 "0"s
               Iè    # Index the integer (with automatic wraparound) into it
                 (   # Negate the result
O                    # Sum all values on the stack (and output implicitly)

Vedere questo 05AB1E risposta di mine (sezione Come comprimere grandi numeri interi? ) Per capire il motivo per cui •Ž¢Γ}Þ±6u•è 10000000001021111111.

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.