Berapa banyak suku kata dalam jumlah itu?

15

Saya ingin mengambil nomor dan tahu berapa banyak suku kata di dalamnya, ketika berbicara dalam bahasa Inggris.

Mari kita batasi ini pada bilangan bulat positif yang kurang dari seribu.

Saya orang Inggris, jadi kami akan mengikuti ratusan kolom dengan tanda 'dan' ketika ada angka yang tidak nol setelahnya.

Tantangan

  • Tulis beberapa kode yang akan menerima bilangan bulat positif lebih rendah dari 1000 dan menampilkan jumlah suku kata dengan kata-kata yang mewakili angka itu dalam bahasa Inggris Inggris.
  • Ini TIDAK perlu menghasilkan kata-kata untuk mewakili angka, hanya jumlah suku kata yang dikandungnya.
  • Ini kode golf, upaya untuk mencapai ini dalam byte paling sedikit.
  • Gunakan bahasa apa pun yang Anda suka.
  • Celah standar dilarang.

Uji Kasus

|  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
sumber
1
Bisakah kita mengambil input sebagai string atau array angka?
Dennis

Jawaban:

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

Terima kasih kepada @xnor untuk bermain golf 9 16 byte!

Cobalah 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')

Mudah, tetapi lebih lama.

Cobalah online!

Dennis
sumber
Untuk solusi 83-byte Anda, Anda dapat memotong 3 byte dengan mengubah -10ke ~9dan beralih sekitar bit terakhir untuk +(0<n%100!=12)-(n%100!=11), tapi itu masih lebih lama dari solusi baru Anda.
xnor
@ xnor Itu benar-benar pintar! min(n%100,13)%12/~9sebenarnya bisa membantu dengan pendekatan yang saya coba untuk jawaban Jelly saya juga.
Dennis
Sebenarnya, hanya mendorong sesuatu menjadi konstanta hardcode ternyata lebih pendek.
xnor
@ xnor Terima kasih lagi!
Dennis
8

Perl 5 -p , 53 byte

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

Cobalah online!

Bagaimana

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

Cobalah online!

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

Cobalah online!

-4 byte, terima kasih untuk Shaggy

TFeld
sumber
2
Selain itu, [2]*7bagian Anda akan gagal 17, karena seharusnya 3 bukannya 2 ( sev-en-teen).
Kevin Cruijssen
2
-4 byte , termasuk perbaikan untuk 17.
Shaggy
@Shaggy Terima kasih :)
TFeld
@KevinCruijssen Diperbaiki sekarang (terima kasih kepada Shaggy)
TFeld
6

Bahasa Wolfram 101 115 Bytes

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

Penjelasan

(mengganti StringSplituntuk s)

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

IntegerNamemembuat angka dalam bahasa Inggris Amerika (yaitu tanpa "dan" termasuk dalam angka lebih besar dari 100.) Misalnya 777-> "seven hundred seventy-seven.

StringSplit[IntegerName@#,"-"] menghapus tanda hubung dalam rendering.

StringSplit/@ membagi rendering menjadi kata-kata.

Join@@ meninggalkan daftar kata-kata sederhana, tanpa daftar yang disematkan (dalam hal tanda hubung muncul).

WordData[#,"Hyphenation"] memecah satu kata menjadi suku kata.

Join@@ meninggalkan daftar suku kata sederhana di semua kata.

Length menghitung suku kata

+Boole[#>100&&#~Mod~100!=0]menambah 1jumlah suku kata untuk angka-angka yang lebih besar dari 100 (karena penambahan "dan" yang digunakan dalam render Inggris Inggris), tidak termasuk kelipatan integral dari 100.

DavidC
sumber
6

Java 11, 105 102 byte

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

Berisi banyak karakter yang tidak patut dicetak.

-3 byte terima kasih @ OlivierGrégoire .

Cobalah online.

Penjelasan:


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
sumber
1
102 byte dengan mengubah .split("7",-1)ke .split("7",9), dan -6+(n>99?4:0)ke -(n>99?2:6).
Olivier Grégoire
1
@ OlivierGrégoire Terima kasih. Benar-benar terjawab -(n>99?2:6), tetapi sekarang sudah sangat jelas bahwa Anda telah menunjukkannya. Dan -1untuk 9karena keterbatasan input-ukuran saya tidak akan memikirkan, jadi terima kasih!
Kevin Cruijssen
5

05AB1E , 34 31 byte

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

Cobalah secara online atau verifikasi semua [1,999]kasus uji .

Penjelasan:

Dengan semua cek yang disebutkan akan menghasilkan 1 untuk kebenaran dan 0 untuk 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
sumber
Ini gagal pada 700 test case. 'Seven Hundred' memiliki 4 suku kata, ini mengembalikan 5.
AJFaraday
@AJFaraday Harus diperbaiki sekarang. Secara tidak sengaja memiliki I(input) alih-alih X(input mod 100) ketika memeriksa apakah lebih besar dari 20 untuk +1 ty.
Kevin Cruijssen
Maaf, mengembalikan 0 untuk 'seratus'
AJFaraday
@AJFaraday Tetap lagi .. >(periksa apakah input lebih besar dari 100) telah diganti dengan @(periksa apakah input lebih besar atau sama dengan 100). Mungkin saya harus memeriksa beberapa test case lebih hati-hati sebelum memposting .. Maaf tentang itu ..
Kevin Cruijssen
4
Ngomong-ngomong, cintai topi paling atas di rubix cube!
AJFaraday
5

Arang , 39 31 byte

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

Cobalah online! Tautan adalah untuk mengucapkan versi kode. Penjelasan:

I⁻⁺

Hitung penyesuaian jumlah suku kata dan hasilkan sebagai string.

↨E謬Iι²

Mulailah dengan mengubah setiap digit bukan nol ke 1 dan kemudian mendekodekan sebagai basis 2. Ini memberikan jawaban yang benar untuk sebagian besar input.

№θ7

Tambahkan 1 untuk masing-masing 7.

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

Ambil string literal 10000000001021111111dan tambahkan 80 nol, kemudian secara siklikal indeks dengan input, dan kurangi angka itu.

Neil
sumber
4

Jelly , 28 25 23 byte

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

Cobalah online!

Bagaimana itu bekerja

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

Cobalah online!

Port solusi Kevin Cruijssen (sayangnya ia tidak memiliki keringkasan yang sama dalam PHP :))

- 32 45 terima kasih untuk Shaggy!

-3 Terima kasih kepada Kevin Crujissen!

NK1406
sumber
Jadi banyak tabungan yang akan dibuat di sini! Berikut ini beberapa yang sangat cepat
Shaggy
1
145 byte . Anda dapat menyimpan beberapa byte lagi menggunakan tag pendek tapi saya tidak ingat bagaimana menggunakannya di TIO. (Catatan: Saya menggunakan ponsel saya jadi belum menguji semua input.)
Shaggy
1
@Shaggy 2 byte lagi dapat diubah saat menggunakan >99dan >19bukannya >=100dan >=20.
Kevin Cruijssen
1
@KevinCruijssen sebenarnya yang menghemat 3 byte karena itu akan dari 100 menjadi 99 :)
NK1406
Saya juga berhasil menyimpan byte lain dengan menempatkan variabel di awal gema.
NK1406
2

05AB1E , 24 byte

Jawaban jeli Port of Dennis

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

Cobalah online! atau sebagai Test suite

Penjelasan

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
sumber
1

05AB1E , 26 byte

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

Port of @Neil 's Charcoal answer , jadi pastikan untuk menghapusnya juga jika Anda suka jawaban ini!

Cobalah secara online atau verifikasi semua kasus uji .

Bilangan bulat terkompresi •Ž¢Γ}Þ±6u•dapat juga •8JA•b2TÌǝuntuk byte-count yang sama.

Penjelasan:

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

Lihat ini 05AB1E jawaban saya (bagian Cara kompres bilangan bulat besar? ) Untuk memahami mengapa •Ž¢Γ}Þ±6u•adalah 10000000001021111111.

Kevin Cruijssen
sumber