¿Cuántas sílabas hay en ese número?

15

Me encantaría tomar un número y saber cuántas sílabas contiene cuando se habla en inglés.

Limitemos esto a enteros positivos que son menos de mil.

Soy británico, así que vamos a seguir la columna de las centenas con un 'y' cuando haya dígitos distintos de cero después.

El reto

  • Escriba un código que acepte un número entero positivo inferior a 1000 y genere el número de sílabas en las palabras que representan ese número en inglés británico.
  • NO necesita generar las palabras para representar los números, solo el número de sílabas que contienen.
  • Es un código de golf, intente lograr esto en la menor cantidad de bytes.
  • Usa el idioma que quieras.
  • Las lagunas estándar están prohibidas.

Casos de prueba

|  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 |
AJFaraday
fuente
1
¿Podemos tomar la entrada como una cadena o una matriz de dígitos?
Dennis

Respuestas:

11

Python 2 , 84 83 74 67 bytes

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

¡Gracias a @xnor por jugar 9 16 bytes!

Pruébalo en línea!


Python 2 , 79 bytes

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

Directo, pero más largo.

Pruébalo en línea!

Dennis
fuente
Para su solución de 83 bytes, se puede cortar 3 bytes cambiando -10a ~9y cambiar todo el último bit a +(0<n%100!=12)-(n%100!=11), pero eso es todavía más largo que su nueva solución.
xnor
@xnor ¡Eso es muy inteligente! min(n%100,13)%12/~9en realidad podría ayudar con un enfoque que estaba tratando de obtener mi respuesta de Jelly también.
Dennis
En realidad, simplemente empujar las cosas en una constante codificada resulta más corto.
xnor
@xnor Gracias de nuevo!
Dennis
8

Perl 5 -p , 53 bytes

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

Pruébalo en línea!

Cómo

-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 $_
Xcali
fuente
7

JavaScript (ES6), 89 bytes

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

Pruébalo en línea!

Arnauld
fuente
7

Python 2 , 112 108 bytes

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

Pruébalo en línea!

-4 bytes, gracias a Shaggy

TFeld
fuente
2
Además, su [2]*7parte fallará 17, ya que debería ser 3 en lugar de 2 ( sev-en-teen).
Kevin Cruijssen
2
-4 bytes , incluida una solución para 17.
Shaggy
@Shaggy Gracias :)
TFeld
@KevinCruijssen Corregido ahora (gracias a Shaggy)
TFeld
6

Wolfram Language 101 115 Bytes

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

Explicación

(sustituyendo StringSplitpor s)

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

IntegerNamerepresenta el número en inglés americano (es decir, sin "y" incluido en números mayores que 100.) Ej 777-> "seven hundred seventy-seven.

StringSplit[IntegerName@#,"-"] elimina cualquier guión en el renderizado.

StringSplit/@ divide la representación en palabras.

Join@@ deja una lista simple de palabras, sin lista incrustada (en el caso de que aparezca un guión).

WordData[#,"Hyphenation"] divide una sola palabra en sus sílabas.

Join@@ deja una lista simple de sílabas en todas las palabras.

Length cuenta las sílabas

+Boole[#>100&&#~Mod~100!=0]se suma 1al recuento de sílabas para aquellos números mayores que 100 (debido a los "y" adicionales empleados en la representación en inglés británico), excluyendo los múltiplos integrales de 100.

DavidC
fuente
6

Java 11, 105 102 bytes

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

Contiene montones de caracteres no imprimibles.

-3 bytes gracias @ OlivierGrégoire .

Pruébalo en línea.

Explicación:


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)
Kevin Cruijssen
fuente
1
102 bytes cambiando .split("7",-1)a .split("7",9), y -6+(n>99?4:0)a -(n>99?2:6).
Olivier Grégoire
1
@ OlivierGrégoire Gracias. Completamente perdido -(n>99?2:6), pero es tan obvio ahora que lo has señalado. Y -1a 9causa de la entrada de tamaño limitado yo no habría pensado, así que gracias!
Kevin Cruijssen
5

05AB1E , 34 31 bytes

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

Pruébelo en línea o verifique todos [1,999]los casos de prueba .

Explicación:

Con todas las verificaciones mencionadas, resultará en 1 para veracidad y 0 para falsey.

т%         # 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
Kevin Cruijssen
fuente
Esto falla el caso de prueba 700. 'Seven Hundred' tiene 4 sílabas, esto devuelve 5.
AJFaraday
@AJFaraday Debería arreglarse ahora. Accidentalmente tuvo I(input) en lugar de X(input mod 100) al verificar si es mayor que 20 para el +1 de ty.
Kevin Cruijssen
Lo siento mucho, devuelve 0 para 'cien'
AJFaraday
@AJFaraday Se corrigió nuevamente ... >(verifique si la entrada es mayor que 100) se ha reemplazado por @(verifique si la entrada es mayor o igual a 100). Tal vez debería haber revisado algunos casos de prueba más cuidadosamente antes de publicar ... Lo siento por eso ...
Kevin Cruijssen
44
Por cierto, ¡me encanta el sombrero de copa en un cubo de rubix!
AJFaraday
5

Carbón , 39 31 bytes

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

Pruébalo en línea! El enlace es a la versión detallada del código. Explicación:

I⁻⁺

Calcule los ajustes en el número de sílabas y envíe el resultado como una cadena.

↨E謬Iι²

Comience cambiando cada dígito que no sea cero a 1 y luego decodifique como base 2. Esto proporciona la respuesta correcta para la mayoría de las entradas.

№θ7

Agregue 1 para cada uno 7.

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

Tome la cadena literal 10000000001021111111y agregue 80 ceros, luego indexe cíclicamente por la entrada y reste ese dígito.

Neil
fuente
4

Gelatina , 28 25 23 bytes

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

Pruébalo en línea!

Cómo funciona

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.
Dennis
fuente
3

PHP , 190 158 145 141 137 bytes

<?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);

Pruébalo en línea!

Un puerto de la solución de Kevin Cruijssen (desafortunadamente no tiene la misma brevedad en PHP :))

- 32 45 gracias a Shaggy!

-3 gracias a Kevin Crujissen!

NK1406
fuente
¡ Tantos ahorros por hacer aquí! Aquí hay algunos muy rápidos
Shaggy
1
145 bytes . Puede guardar algunos bytes más con etiquetas cortas, pero no recuerdo cómo usarlos en TIO. (Nota: estoy en mi teléfono, así que no he probado todas las entradas).
Shaggy
1
@Shaggy Se pueden cambiar 2 bytes más cuando se usa >99y en >19lugar de >=100y >=20.
Kevin Cruijssen
1
@KevinCruijssen en realidad ahorra 3 bytes porque va de 100 a 99 :)
NK1406
También logré guardar otro byte colocando la variable al comienzo del eco.
NK1406
2

05AB1E , 24 bytes

Respuesta de jalea del puerto de Dennis

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

Pruébalo en línea! o como un conjunto de pruebas

Explicación

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
Emigna
fuente
1

05AB1E , 26 bytes

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

Respuesta de Port of @Neil 's Charcoal , ¡así que asegúrate de votarlo también si te gusta esta respuesta!

Pruébelo en línea o verifique todos los casos de prueba .

El número entero comprimido •Ž¢Γ}Þ±6u•puede ser alternativamente •8JA•b2TÌǝpara el mismo número de bytes.

Explicación:

€Ā                   # 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)

Ver este 05AB1E respuesta mío (sección Cómo comprimir grandes números enteros? ) Para entender por qué •Ž¢Γ}Þ±6u•es 10000000001021111111.

Kevin Cruijssen
fuente