Nomor telepon dengan kata-kata yang diucapkan

33

Tujuan

Tulis program atau fungsi yang menerjemahkan nomor telepon numerik ke dalam teks yang membuatnya mudah untuk diucapkan. Ketika digit diulang, mereka harus dibaca "double n" atau "triple n".

Persyaratan

Memasukkan

Sederetan angka.

  • Asumsikan semua karakter adalah digit dari 0 hingga 9.
  • Asumsikan string berisi setidaknya satu karakter.

Keluaran

Kata-kata, dipisahkan oleh spasi, tentang bagaimana angka-angka ini dapat dibaca dengan keras.

  • Terjemahkan digit ke kata:

    0 "oh"
    1 "satu"
    2 "dua"
    3 "tiga"
    4 "empat"
    5 "lima"
    6 "enam"
    7 "tujuh"
    8 "delapan"
    9 "sembilan"

  • Ketika angka yang sama diulang dua kali berturut-turut, tulis " angka ganda ".

  • Ketika angka yang sama diulang tiga kali berturut-turut, tulis " angka tiga ".
  • Ketika digit yang sama diulang empat atau lebih kali, tulis " angka ganda " untuk dua digit pertama dan evaluasi sisa string.
  • Hanya ada satu karakter spasi di antara setiap kata. Satu ruang terkemuka atau tambahan dapat diterima.
  • Output tidak peka huruf besar-kecil.

Mencetak gol

Kode sumber dengan byte paling sedikit.

Uji Kasus

input        output
-------------------
0123         oh one two three
4554554      four double five four double five four
000          triple oh
00000        double oh triple oh
66667888     double six double six seven triple eight
19999999179  one double nine double nine triple nine one seven nine
Makanan Tangan
sumber
38
Siapa pun yang tertarik dengan "wicara golf" harus mencatat bahwa "gandakan enam" membutuhkan waktu lebih lama untuk mengatakan daripada "enam enam". Dari semua kemungkinan numerik di sini, hanya "triple seven" yang menyimpan suku kata.
Purple P
13
@Purple P: Dan seperti yang saya yakin Anda tahu, 'double-u double-u double-u'> 'world wide web' ..
Chas Brown
11
Saya memilih untuk mengubah surat itu menjadi "dub".
Hand-E-Food
8
Saya tahu ini hanya latihan intelektual, tetapi di depan saya ada tagihan gas dengan nomor 0800 048 1000, dan saya akan membacanya sebagai "oh delapan ratus oh empat delapan seribu". Pengelompokan angka penting bagi pembaca manusia, dan beberapa pola seperti "0800" diperlakukan secara khusus.
Michael Kay
3
@PurpleP Siapa saja yang tertarik pada kejelasan bicara, terutama ketika berbicara melalui telepon, mungkin ingin menggunakan "double 6" karena lebih jelas bahwa speaker berarti dua enam dan tidak mengulangi nomor 6 secara tidak sengaja. Orang-orang bukan robot: P
Permintaan maaf dan kembalikan Monica

Jawaban:

10

05AB1E , 53 52 51 50 49 byte

γε€T2äθ¬MÊi¨₃1ǝR]˜“Šç€µ‚•„í†ìˆÈŒšï¿Ÿ¯¥Š‹¶½¿“#s踻

Cobalah online!

Penjelasan:

γ                      # split input in groups of consecutive equal digits
 ε              ]      # for each group
  €T                   #  add a 10 before each digit (66 -> [10, 6, 10, 6])
    2äθ                #  keep only the second half of that list
       ¬MÊi     ]      #  if the first element is not the maximum
           ¨           #   drop the last element
            ₃1ǝ        #   replace the second element with 95
               R       #   reverse the list
˜                      # flatten
 “...“                 # compressed string: "oh one two ... nine double triple"
      #                # split on spaces
       sè              # index (wraps around, so 95 yields "triple")
         ¸»            # join with spaces
Grimmy
sumber
1
Oh, Mjuga melihat ke dalam daftar ketika menentukan integer maksimum pada stack? Tidak tahu itu. Kedengarannya seperti sesuatu yang perlu diingat. :)
Kevin Cruijssen
16

8088 Majelis, IBM PC DOS, 164 159 156 155 byte

Biner:

00000000: d1ee 8a0c 03f1 53fd ac3a d075 0343 e2f7  ......S..:.u.C..
00000010: 85db 741c 5f8a d043 f6c3 0174 0a57 bd64  ..t._..C...t.W.d
00000020: 0155 83eb 0374 0957 bd5d 0155 4b4b 75f7  .U...t.W.].UKKu.
00000030: 8ad0 2c2f 7213 518a f0b0 24b1 31bf 6a01  ..,/r.Q...$.1.j.
00000040: fcf2 aefe ce75 fa59 57e2 bc5a 85d2 740c  .....u.YW..Z..t.
00000050: b409 cd21 b220 b402 cd21 ebef c364 6f75  ...!. ...!...dou
00000060: 626c 6524 7472 6970 6c65 246f 6824 6f6e  ble$triple$oh$on
00000070: 6524 7477 6f24 7468 7265 6524 666f 7572  e$two$three$four
00000080: 2466 6976 6524 7369 7824 7365 7665 6e24  $five$six$seven$
00000090: 6569 6768 7424 6e69 6e65 24              eight$nine$

Bangun dan uji yang dapat dieksekusi dengan menggunakan xxd -rdari atas, atau unduh PHONE.COM .

Daftar belum dirakit:

D1 EE       SHR  SI, 1              ; point SI to DOS PSP (80H) for input string
8A 0C       MOV  CL, BYTE PTR[SI]   ; load input string length into CX
03 F1       ADD  SI, CX             ; move SI to end of input 
53          PUSH BX                 ; push a 0 to signal end of output stack 
        CHAR_LOOP:
FD          STD                     ; set LODS direction to reverse 
AC          LODSB                   ; load next char from [SI] into AL, advance SI 
3A D0       CMP  DL, AL             ; is it same as previous char? 
75 03       JNZ  NEW_CHAR           ; if not, it's a different char 
43          INC  BX                 ; otherwise it's a run, so increment run length
E2 F7       LOOP CHAR_LOOP          ; move on to next char 
        NEW_CHAR: 
85 DB       TEST BX, BX             ; is there a run greater than 0? 
74 1C       JZ   GET_WORD           ; if not, look up digit name 
5F          POP  DI                 ; get name for the current digit 
8A D0       MOV  DL, AL             ; save current char in DL 
43          INC  BX                 ; adjust run count (BX=1 means run of 2, etc)
F6 C3 01    TEST BL, 1              ; is odd? if so, it's a triple
74 0A       JZ   IS_DBL             ; is even, so is a double 
57          PUSH DI                 ; push number string ("one", etc) to stack
BD 0164     MOV  BP, OFFSET T       ; load "triple" string 
55          PUSH BP                 ; push to stack 
83 EB 03    SUB  BX, 3              ; decrement run count by 3 
74 09       JZ   GET_WORD           ; if end of run, move to next input char 
        IS_DBL: 
57          PUSH DI                 ; push number string to stack
BD 015D     MOV  BP, OFFSET D       ; load "double" string 
55          PUSH BP                 ; push to stack 
4B          DEC  BX                 ; decrement by 2
4B          DEC  BX
75 F7       JNZ  IS_DBL             ; if not end of run, loop double again 
        GET_WORD: 
8A D0       MOV  DL, AL             ; save current char into DL
2C 2F       SUB  AL, '0'-1          ; convert ASCII char to 1-based index 
72 13       JB   NOT_FOUND          ; if not a valid char, move to next
51          PUSH CX                 ; save outer loop counter 
8A F0       MOV  DH, AL             ; DH is the index to find, use as scan loop counter
B0 24       MOV  AL, '$'            ; word string is $ delimited
B1 31       MOV  CL, 031H           ; search through length of word data (49 bytes)
BF 016A     MOV  DI, OFFSET W       ; reset word data pointer to beginning
FC          CLD                     ; set DF to scan forward for SCAS 
        SCAN_LOOP: 
F2/ AE      REPNZ SCASB             ; search until delimiter '$' is found in [DI]
FE CE       DEC  DH                 ; delimiter found, decrement counter 
75 FA       JNZ  SCAN_LOOP          ; if counter reached 0, index has been found 
59          POP  CX                 ; restore outer loop position
57          PUSH DI                 ; push string on stack 
        NOT_FOUND:
E2 BC       LOOP CHAR_LOOP          ; move to next char in input 
        OUTPUT_STACK: 
5A          POP  DX                 ; get string from top of stack 
85 D2       TEST DX, DX             ; it is the last? 
74 0C       JZ   EXIT               ; if so, exit 
B4 09       MOV  AH, 09H            ; DOS display string function 
CD 21       INT  21H                ; write string to console 
B2 20       MOV  DL, ' '            ; load space delimiter 
B4 02       MOV  AH, 02H            ; DOS display char function 
CD 21       INT  21H                ; write char to console 
EB EF       JMP  OUTPUT_STACK       ; continue looping 
        EXIT: 
C3          RET                     ; return to DOS 

D   DB "double$" 
T   DB "triple"
W   DB "$oh$","one$","two$","three$","four$","five$","six$","seven$","eight$","nine$" 

TL; DR:

String input dibaca dari kanan ke kiri untuk memudahkan menemukan triple. Output didorong ke stack x86 untuk mempermudah membalik urutan tampilan dan juga memfasilitasi menata ulang kata-kata "ganda" dan "tiga" untuk mendahului nama digit.

Jika digit berikutnya berbeda dari yang terakhir, nama tersebut terlihat dalam daftar kata dan didorong ke tumpukan. Karena tidak ada konsep formal dari "array yang diindeks dari string panjang variabel" dalam kode mesin, daftar kata dipindai i(indeks kata) beberapa kali untuk pembatas string ( $) untuk menemukan kata yang sesuai. Membantu, x86 memang memiliki sepasang petunjuk singkat ( REPNZ SCASByang mirip dengan memchr()di C), yang menyederhanakan ini (terima kasih CISC !).

Jika digit sama dengan yang sebelumnya, penghitung untuk panjang "run" bertambah dan terus looping ke kiri pada input. Setelah proses selesai, nama digit diambil dari tumpukan karena harus ditempatkan setelah "dobel" atau "rangkap tiga" untuk setiap pengelompokan. Jika panjang run adalah ganjil (dan run run adalah > 1), nama digit yang diikuti oleh string "triple" didorong ke stack dan panjang run dikurangi oleh 3. Karena panjang run sekarang akan genap, langkah diulang untuk "double" hingga panjang run adalah 0.

Ketika string input telah mencapai akhir, tumpukan dibuang dengan setiap string yang disimpan ditulis ke layar dalam urutan terbalik.

I / O:

PC DOS mandiri yang dapat dieksekusi, input dari output baris perintah ke konsol.

masukkan deskripsi gambar di sini

Unduh dan uji PHONE.COM .

640KB
sumber
repne scasbadalah memchr(atau strchrjika Anda tahu akan ada hit), tidak strstr.
Peter Cordes
Apakah CH = 0 pada entri proses dijamin oleh standar, atau hanya itu yang dilakukan oleh beberapa versi DOS? Saya perhatikan Anda menganggap itu mov cl, byte[si] setara dengan movzx cx, byte [si]. Saya ingin tahu apakah menggunakan reg yang berbeda, seperti AH, untuk hitungan dengan dec ah / jnzbukannya loopakan menghemat apa pun dari tidak harus mendorong / pop CX. Mungkin tidak, dan Anda tidak memiliki regs 16-bit yang tersisa yang memungkinkan 1-byte dec.
Peter Cordes
1
@PeterCordes, untuk CH=0saya pergi oleh fysnet.net/yourhelp.htm , yang untuk setiap rilis wajar dari DOS selalu nol, sama dengan BX. Pemikiran yang baik tentang zero- extended mov, meskipun secara teknis saya tidak berpikir movzxtersedia pada 808x (menjaga platform target IBM PC 5150 dan semua). Saya mengutak-atik semua register sebaik mungkin untuk menyelamatkan byte, tetapi jika Anda melihat sesuatu yang mungkin terlewat, tolong beri tahu saya!
640KB
1
Lebih akurat menyebutnya memchrIMO. Penamaan "instruksi string" menyesatkan orang untuk berpikir bahwa mereka bekerja pada string C panjang-implisit, tetapi benar-benar mereka bekerja pada string seperti panjang eksplisit std::stringatau buffer. Seperti memcpy, memset(movs / stos), memchr/ memrchr(repne scas dengan DF = 0 atau 1), dan memcmp(repe cmps). Satu-satunya yang setara dengan C repe scasadalah strspnkarena saya tidak berpikir ada memfungsi untuk itu. Anda bahkan dapat menggambarkan stoswatau stosdsebagai wmemsetcontoh.
Peter Cordes
1
movzxbiaya byte opcode tambahan, dan ya itu hanya diperkenalkan dengan 386. Itu hanya lebih mudah untuk mengetikkan fakta bahwa Anda sedang melakukan penggabungan byte-rendah dan menganggap itu benar diperpanjang nol. Jika Anda tahu CX atau setidaknya CH = 0, maka ya untuk bermain golf selalu gunakan movCL. Tetapi di luar bermain golf, instruksi x86's go-to-load-load adalah movzxdan movsx: mereka menghindari dependensi salah atau shenanigans register parsial lainnya. Pada CPU modern dengan tujuan kata, mereka secepat mov memuat kata.
Peter Cordes
9

05AB1E , 61 56 53 52 51 byte

γvyDg;LàäRv… ‹¶½¿#yg蓊瀵‚•„í†ìˆÈŒšï¿Ÿ¯¥Š“#yè])áðý

-9 byte terima kasih kepada @Grimy .

Cobalah secara online atau verifikasi semua kasus uji .

Penjelasan:

γ               # Split the (implicit) input into substrings of equal adjacent characters
                #  i.e. "199999991779" → ["1","9999999","1","77","9"]
 v              # Loop over each substring `y`:
   Dg           #  Get the length of a copy of the substring
     ;          #  Halve it
      L         #  Create a list in the range [1, length/2], where odd lengths are
                #  automatically truncated/floored
                #   i.e. "1" (length=1) → 0.5 → [1,0]
                #   i.e. "9999999" (length=7) → 3.5 → [1,2,3]
       à        #  Pop and push the maximum of this list
  y     ä       #  Divide the string into that many parts
                #   → ["1"]
                #   → ["999","99","99"]
         R      #  Reverse the list
                #   → ["99","99","999"]
  v             # Inner loop over each item `y`:
    ‹¶½¿       #  Push dictionary word: "  double triple"
         #      #  Split it on spaces: ["","","double","triple"]
          yg    #  Get the length of the current item `y`
            è   #  And use it to (0-based) index into the list
   “Šç€µ‚•„í†ìˆÈŒšï¿Ÿ¯¥Š“
                #  Push dictionary string "oh two three four five six seven eight nine"
     #          #  Split it on spaces: ["oh","two","three",...,"nine"]
      yè        #  Use `y` to index into the string-list (with automatic wrap-around,
                #  so since there are 10 words, it basically indexes with a single digit
                #  due to an implicit modulo-10)
                #   i.e. "77" → "seven"
 ]              # Close both loops
  )             # Wrap all values on the stack into a list
   á            # Only keep letters, which removes the empty strings from the list
    ðý          # And join the list on spaces
                # (after which the result is output implicitly)

Lihat ini 05AB1E ujung tambang (bagian Cara menggunakan kamus? ) Untuk memahami mengapa … ‹¶½¿adalah" double triple" dan “Šç€µ‚•„í†ìˆÈŒšï¿Ÿ¯¥Š“itu "oh two three four five six seven eight nine".

Kevin Cruijssen
sumber
1
@Grimy Ah, tentu saja .. saya menambahkan if(length>=4)sebelum menambahkan sisanya, tapi tentu saja itu tidak perlu untuk bilangan bulat ukuran 1,2,3, karena ;Å2¨3ª£akan meninggalkan string utuh (hanya dibungkus dalam daftar kami meratakan setelah peta pula). Terima kasih telah memperhatikan! Dan melihat ke depan melihat jawaban Anda bersama Åγ. Aku memang merasa bagian pertama bisa dilakukan jauh lebih pendek.
Kevin Cruijssen
1
Dg;LàäRmasih satu byte lebih pendek dari āɨšJõK, dan jauh lebih mirip dengan yang Anda miliki sebelumnya.
Grimmy
1
@ Grimy Ah, itu memang tertutup untuk apa yang awalnya saya miliki, saya menyukainya. :) Terima kasih lagi!
Kevin Cruijssen
1
@ Grimy Sudah bisa menemukan satu lagi golf yang saya lupa .. ádaripada õKdi akhir. :)
Kevin Cruijssen
1
Nice ditemukan dengan á! Inilah 51 dan satu lagi . 50 terasa mungkin.
Grimmy
7

QuadR , 137 byte SBCS

Kasing judul dengan spasi terdepan.

∊¯2↑¨@(∊∘⎕A)⍵
(.)\1*
{⍺←(,¨⎕D)⎕R('OhOneTwoThreeFourFiveSixSevenEightNine'(∊⊂⊣)⎕A)⋄' 'w←⍺,⊃⍵:⍬⋄1=≢⍵:⍺⍵⋄3=≢⍵:'Triple',w'Double',w,∇2↓⍵}⍵M

Cobalah online!

ϵ daftar (ratakan)
¯2↑¨ ambil dua karakter terakhir (padding ke kiri dengan spasi) dari setiap karakter
@ pada posisi di mana
(∊∘⎕A) karakter adalah anggota huruf besar A lfabet
 dalam hasil dari operasi Ganti PCRE di bawah ini ...

(.) setiap karakter
\1 diikuti dengan sendirinya
*  nol atau lebih banyak kali, digantikan oleh hasil dari yang berikut ...

{…}⍵M "dfn"; adalah M atch dari pola di atas

('OhOneTwoThreeFourFiveSixSevenEightNine'(... )⎕A) terapkan fungsi diam-diam anonim berikut dengan string panjang dan huruf besar A sebagai argumen kiri:

 keanggotaan (huruf dalam string panjang dalam alfabet huruf besar)

 partisi (dengan awal partisi baru setiap kali is-a-member

 argumen kiri (yaitu string panjang)

()⎕R PCRE R ganti pola-pola berikut dengan kata-kata itu:

⎕D digit 0 hingga 9

 perlakukan masing-masing sebagai pola yang terpisah

⍺← menetapkan fungsi pengganti ini untuk (untuk sebuah lphabetise)

kemudian,

⊃⍵ karakter pertama pertandingan

, sebagai string

 terapkan untuk itu

w← tetapkan ini ke w(untuk kata )

' '∊... : jika ruang adalah anggota daripadanya (yaitu jika pertandingan kosong):

 mengembalikan apa-apa (menjadi string kosong)

 lain,

1=≢⍵: jika satu sama dengan penghitungan karakter dalam pertandingan (yaitu panjangnya):

⍺⍵ abjad digit itu

 lain,

3=≢⍵: jika tiga sama dengan penghitungan karakter dalam pertandingan (yaitu panjangnya):

'Triple',w tambahkan "Triple" ke w ord

 lain,

2↓⍵ turun ke angka dari pertandingan

 ulangi itu

w, tambahkan kata

'Double', tambahkan "Double"

Adm
sumber
6

JavaScript (ES6),  161 160 152  144 byte

Outputnya termasuk ruang terkemuka tunggal.

s=>[n=>' '+'oh/one/two/three/four/five/six/seven/eight/nine'.split`/`[n],'$1 double$2','triple$2'].map(r=>s=s.replace(/(\S*)( \S+)\2|\d/g,r))&&s

Cobalah online!

atau Lihat kode sumber yang diformat

Bagaimana?

Konversi diproses dalam tiga langkah:

  1. ganti setiap digit dengan kata bahasa Inggris yang sesuai, didahului oleh spasi
  2. ganti setiap pola "X X"dengan"double X"
  3. ganti setiap pola "double X X"dengan"triple X"

Untuk menyimpan byte, kami menggunakan persamaan reguler yang sama untuk semua langkah:

/(\S*)( \S+)\2|\d/g

yang berfungsi sebagai berikut:

(\S*)  -> 1st capturing group: any word, or nothing at all
( \S+) -> 2nd capturing group: a space, followed by a word
\2     -> a copy of the 2nd capturing group
|\d    -> or try to capture a digit instead (for step 1)

Pada langkah 1, kami menggunakan fungsi panggilan balik yang mengambil kata yang benar dari tabel pencarian:

  • "799999"" seven nine nine nine nine nine"

Pada langkah 2, kami ganti dengan "$1 double$2":

  • " (seven)( nine)( nine)"" seven double nine"
  • "( nine)( nine) nine"" double nine nine"

Pada langkah 3, kami ganti dengan "triple$2":

  • " (double)( nine)( nine)"" triple nine"
Arnauld
sumber
4

Bahasa Wolfram (Mathematica) , 115 byte

{Switch[L=Tr[1^{##}],1," ",3," triple ",_," double "],If[#<1,"oh",IntegerName@#],If[L>3,#0@##3,""]}&@@@Split@#<>""&

Cobalah online!

Mengambil daftar digit sebagai input. Output mencakup ruang terdepan.

attinat
sumber
4

Stax , 56 byte

ÇÖ◘⌡¿╒ô╞Γ▓8m☻t7♦3├(Ä⌂≤(┬Ω☻9▲ç╕C╞⌡òσ╗─╣╥─☻╪▼⌡5■ÿ,(┬¥?☺÷•±

Jalankan dan debug itu

rekursif
sumber
3

Python 2 , 171 169 168 byte

s=input()
while s:c=s[0];n=(s[1:2]==c)+(s[:3]==c*3!=s[1:4]);print'   eellpbiurotd'[-n:0:-2]+'oh one two three four five six seven eight nine'.split()[int(c)],;s=s[1+n:]

Cobalah online!

-1 byte, terima kasih kepada Jitse

TFeld
sumber
Pukul aku lagi! Simpan 1 byte seperti itu
Jitse
@ Jitse, itu tidak berhasil 1312;)
TFeld
Ah, kamu benar!
Jitse
Bagaimana kalau yang ini: ['','double ','triple '][n]to ' eellpbiurotd'[-n:0:-2]for 168 bytes: Coba online!
Jitse
Atau, juga 168 byte
Jitse
3

Perl 5 -p , 111 byte

s/(\d)\1/ double$1/g;s/\w+(\d)\1/triple$1/g;s/\d/' '.qw(oh one two three four five six seven eigth nine)[$&]/ge

Cobalah online!

Penjelasan:

s/(\d)\1/ double$1/g; # Replace non-overlapping double digits with " double<digit>"
s/\w+(\d)\1/triple$1/g; # Replace remaining double digits preceded by "double" with "triple<digit>"
s/\d/' '.qw(oh one two three four five six seven eigth nine)[$&]/ge # Replace digits with " <word>"
wastl
sumber
1
Memotong
3

Scala , 213 byte

Oke. Entah bagaimana versi rekursif yang saya coba bangun sangat verbose-y lebih dari yang ini (masih rekursif, tetapi hanya dalam satu kasus). Fungsinya fsebagai string input nomor telepon dan mengeluarkan fonetiknya dengan spasi spasi tambahan.

var u="oh one two three four five six seven eight nine" split " "
"(.)\\1*".r.replaceAllIn(s,x=>{var o=x.matched
var k=u(o(0)-48)+" "
o.length match{case 3=>"triple "+k
case 1=>k
case _=>"double "+k+f(o drop 2)}})

Cobalah online!
Sunting : -8b terima kasih kepada DrY Wit!

Scala , 215 byte

Dan inilah versi whitespace terkemuka, dua byte lebih lama untuk beberapa alasan (bahkan dengan refactoring besar-besaran).

var u="oh one two three four five six seven eight nine" split " "
"(.)\\1*".r.replaceAllIn(s,x=>{var o=x.matched
var k=u(o(0)-48)
" , double , triple ".split(",")(if(o.length>3){k+=f(o drop 2);1}else o.length-1)+k})

Cobalah online!

V. Courtois
sumber
2
Anda dapat menyimpan 8 byte dengan menggantinya (o(0)+"").toIntdengan o(0)-48.
Dr Y Wit
Oof well done @DrYWit thanks!
V. Courtois
3

PHP, 174 169 166 159 bytes

for(;$s=strspn($argn,$d=$argn[$i],$i++);$s==3?($i+=2)+print'triple ':$s<2?:++$i+print'double ',print[oh,one,two,three,four,five,six,seven,eight,nine][$d].' ');

Try it online!

For each digit at index of $i starting from 0:

  • Jika rentang angka yang sama mulai dari lokasi $isama dengan 3, cetak 'triple 'dan tambahkan 2 hingga $iiterasi berikutnya akan memiliki 2 digit melompati.
  • Jika rentang dari angka yang sama mulai dari lokasi $isama dengan atau lebih dari 2 tetapi bukan 3, cetak 'double 'dan tambahkan 1 $isehingga iterasi berikutnya akan memiliki 1 digit melompati.
  • Mencetak kata untuk digit dan spasi.
  • $i++.
Night2
sumber
2

Retina 0.8.2 , 105 byte

+`(.)\1
=$1
.
 $&
= =
triple
=
double
9
nine
8
eight
7
seven
6
six
5
five
4
four
3
three
2
two
1
one
0
oh

Cobalah online! Menghasilkan ruang terdepan. Penjelasan: Saya awalnya mencoba regex yang secara otomatis cocok dengan 2 atau 3 digit tetapi pendekatan @ Arnauld berubah menjadi pemain golf. Penjelasan:

+`(.)\1
=$1

Cocokkan pasangan angka identik dan gantikan yang pertama dengan a =. Kemudian ulangi, sehingga untuk nomor ganjil digit terakhir kedua juga diganti dengan a =.

.
 $&

Spasi digit (dan =s) keluar.

= =
triple

Tangani case dari tiga digit yang identik.

=
double
9
nine
8
eight
7
seven
6
six
5
five
4
four
3
three
2
two
1
one
0
oh

Ganti semua karakter yang tersisa dengan kata-kata.

Neil
sumber
2

Jelly , 59 byte

⁵;`,0;$Ɗ€Ẏ;`Ø0ṭ;-œṣjƭƒV€‘$ị“¡ıc⁴Ṛ⁽]@ɱ2¦Ż©Ẉḷ$Æ!)ɗ[ı8ɱḃ%ċ»Ḳ¤K

Cobalah online!

Tautan monadik yang menggunakan string karakter digit sebagai argumennya dan mengembalikan string Jelly kata-kata yang dipisahkan oleh spasi. Ketika dipanggil sebagai program penuh, output secara implisit.

Nick Kennedy
sumber
2

T-SQL 2017, 238 byte

Menambahkan beberapa linebreak agar dapat dibaca

WHILE''<left(@,1)SELECT @=stuff(@,1,iif(p<4,p,2),'')+
iif(p=1,' ',iif(p=3,' triple ',' double '))
+trim(substring('oh  one  two  threefour five six  seveneightnine',left(@,1)*5,5))
FROM(SELECT~-patindex('%[^'+left(@,1)+']%'+'^',@)p)z
PRINT @

Cobalah online

t-clausen.dk
sumber
2

C ++, 382 byte

Ini bukan superclever, tetapi seseorang perlu menulis versi C ++. Fungsi rekursif R melewati string input dan menghitung nilai berulang. Jika ada lebih dari 3 pengulangan, itu berpura-pura ada 2 pengulangan, lalu mundur dan coba lagi.

Beberapa karakter sumber mungkin bisa diperas dengan #definemayor, tapi saya yakin algo yang lebih baik bisa memeras lebih banyak.

#include <iostream>
#include <sstream>
using namespace std;
char*n[]={"oh","one","two","three","four","five","six","seven","eight","nine"};
void R(ostream& s,const char*r,char p='x',int c=0){if(*r==p)R(s,r+1,p,c+1);else
{if(c>1){if(c>= 4){s<<"double ";r-=(c-2);}else if(c==3)s<< "triple ";else if(c==2)s<< "double ";
}if(c >0)s<<n[p-'0']<<" ";if(!*r)return;R(s,r+1,*r,1);}}

void check(const char* in, const char* out)
{
    std::stringstream ss;
    R(ss,in);
    if (out == ss.str()) std::cout << "PASS: "; else std::cout << "FAIL! ";
    std::cout << in << "\n< " << out << "\n> " << ss.str() << std::endl;
}

int main(int c,char**argv)
{
    if (argv[1] == std::string("test"))
    {
        check("0123"         ,"oh one two three ");
        check("4554554"      ,"four double five four double five four ");
        check("000"          ,"triple oh ");
        check("00000"        ,"double oh triple oh ");
        check("66667888"     ,"double six double six seven triple eight ");
        check("19999999179"  ,"one double nine double nine triple nine one seven nine ");
    }
    else
    {
        char* v = argv[1];
        R(std::cout,v);
        std::cout << std::endl;
    }
}

dan verifikasi kasus uji:

pa-dev01$ ./a.out test
PASS: 0123
< oh one two three
> oh one two three
PASS: 4554554
< four double five four double five four
> four double five four double five four
PASS: 000
< triple oh
> triple oh
PASS: 00000
< double oh triple oh
> double oh triple oh
PASS: 66667888
< double six double six seven triple eight
> double six double six seven triple eight
PASS: 19999999179
< one double nine double nine triple nine one seven nine
> one double nine double nine triple nine one seven nine
Mark Lakata
sumber
1
Apakah bagian golf sebenarnya perlu #include <sstream>? Atau bisakah Anda memindahkannya ke bawah setelah bagian golf untuk fungsi tes? Saya pikir mengetik std::ostream&sakan memakan waktu lebih sedikit daripada using namespace std;, kecuali ada tempat lain di mana Anda membutuhkan std::.
Peter Cordes
253 byte
ceilingcat
2

Perl 6 , 96 93 byte

{S:g/(.)$0?[$0{}<!$0>]?/{(<triple double>X$)[3-$/.comb]}{+$/??uniname(~$0).words[1]!!'oh'} /}

Cobalah online!

Ini adalah blok kode anonim yang mengambil angka dan mengembalikan string dengan angka dalam huruf besar, misalnya 0123 => oh ONE TWO THREEdengan satu spasi tambahan.

Ini dihapus untuk sementara waktu sampai saya tahu cara menggunakan tangkapan di lookahead, tetapi harus diperbaiki sekarang.

Jo King
sumber
1

Merah , 242 byte

func[s][b:[copy t skip t]parse s[any[change[b t ahead not t](rejoin["triple "t])|
change b(rejoin["double "t])| skip]]foreach c s[prin either i:
find"0123456789"c[rejoin[pick[:oh:one:two:three:four:five:six:seven:eight:nine]index? i" "]][c]]]

Cobalah online!

Galen Ivanov
sumber
1

Scala , 253 byte

def g(s:String):String={val t="oh one two three four five six seven eight nine".split(" ")(s(0)-48)
s.length match{case 3=>"triple "+t;case 2=>"double "+t;case 1=>t;case _=>"double "+t+" "+g(s drop 2)}}
s=>"(.)\\1*".r.findAllIn(s).map(g(_)) mkString " "

Cobalah online!

Dr Y Wit
sumber
1

Oracle SQL, 578 byte (dalam bentuk yang diformat)

Solusi tidak ringkas dengan cara apa pun sehingga mempostingnya dengan cara yang diformat.

with r(s) as
(select x from t
  union all
 select case
           when length(regexp_substr(s, '(.)(\1)+')) = 3 
           then regexp_replace(s, '^...')
           else regexp_replace(s, '^(.)\1|^.')
        end
   from r
  where s is not null)
select listagg(decode(length(r),  2, 'double ',  3, 'triple ') ||
               decode(substr(r, 1, 1), 0, 'oh', to_char(to_date(substr(r, 1, 1), 'j'), 'jsp')), ' ')
               within group (order by rownum)
  from (select regexp_replace(s, lag(s) over (order by length(s)) || '$') r
          from r order by length(s) desc);

Tes dalam SQL * Plus

SQL> create table t(x) as select /*'45547777777774'*/ '1999999910079' from dual;

Table created.

SQL> set pages 0
SQL> with r(s) as
  2  (select x from t
  3    union all
  4   select case
  5             when length(regexp_substr(s, '(.)(\1)+')) = 3
  6             then regexp_replace(s, '^...')
  7             else regexp_replace(s, '^(.)\1|^.')
  8          end
  9     from r
 10    where s is not null)
 11  select listagg(decode(length(r),  2, 'double ',  3, 'triple ') ||
 12                 decode(substr(r, 1, 1), 0, 'oh', to_char(to_date(substr(r, 1, 1), 'j'), 'jsp')), ' ')
 13                 within group (order by rownum)
 14    from (select regexp_replace(s, lag(s) over (order by length(s)) || '$') r
 15            from r order by length(s) desc);
one double nine double nine triple nine one double oh seven nine

Trik utamanya adalah digit yang dikonversi menjadi kata-kata menggunakan model format Oracle alih-alih literal kode-keras "satu" ... "sembilan".

Dr Y Wit
sumber
ada kemungkinan ini bisa bermain golf? sepertinya Anda dapat menghapus banyak ruang. Saya juga membayangkan Anda dapat menulis ulang WHERE s tidak null ke WHERE s> ''
t-clausen.dk
1
Anda dapat menyimpan beberapa karakter dengan mengganti apa yang ada union alldengan select regexp_replace(s,case when length(regexp_substr(s, '(.)(\1)+')) = 3 then '^...' else '^(.)\1|^.' end) from r.
Steve Kass
1

JavaScript, 142 byte

s=>s.replace(/(.)(\1\1(?!\1)|\1|)/g,t=>(t[2]?' triple ':t[1]?' double ':' ')+'oh one two three four five six seven eight nine'.split` `[t[0]])

Cobalah online!

tsh
sumber
1

(Roblox) Lua 5.1 , 166 byte

for I,N in('111 triple 11 double 1 '):gmatch'(%d+)(%D+)'do for i,n in('0oh1one2two3three4four5five6six7seven8eight9nine'):gmatch'(.)(%l+)'do s=s:gsub(i*I,N..n)end end

Pastikan snilai string yang ditentukan sebelumnya hanya diisi dengan angka; itu akan menjadi variabel yang akan dimodifikasi. Hasilnya akan mencakup karakter ruang terkemuka [\u20] .

VisualPlugin Rōblox
sumber
Selamat datang di situs ini! Karena Lua dapat mengambil input melalui metode standar , itu melanggar aturan untuk mengharuskan ssudah memiliki input. Selain itu, Anda punya posting pertama yang bagus! Saya akan merekomendasikan Anda memasukkan tautan ke situs pengujian online misalnya tio.run/#lua sehingga orang lain dapat menguji solusi Anda
caird coinheringaahing
Hai. Varian Lua I sedang diuji pada (Rbx.Lua) tidak mengandung metode input, meskipun sandbox memiliki metode print, warn, dan error output.
VisualPlugin Rōblox