Số điện thoại bằng lời nói


33

Mục tiêu

Viết chương trình hoặc chức năng dịch số điện thoại số thành văn bản giúp bạn dễ dàng nói. Khi các chữ số được lặp lại, chúng nên được đọc là "double n" hoặc "triple n".

Yêu cầu

Đầu vào

Một chuỗi các chữ số.

  • Giả sử tất cả các ký tự là chữ số từ 0 đến 9.
  • Giả sử chuỗi chứa ít nhất một ký tự.

Đầu ra

Các từ, cách nhau bởi khoảng trắng, về cách các chữ số này có thể được đọc thành tiếng.

  • Dịch chữ số sang từ:

    0 "oh"
    1 "một"
    2 "hai"
    3 "ba"
    4 "bốn"
    5 "năm"
    6 "sáu"
    7 "bảy"
    8 "tám"
    9 "chín"

  • Khi cùng một chữ số được lặp lại hai lần liên tiếp, hãy viết " số kép ".

  • Khi cùng một chữ số được lặp lại ba lần liên tiếp, hãy viết " số ba ".
  • Khi cùng một chữ số được lặp lại bốn lần trở lên, hãy viết " số kép " cho hai chữ số đầu tiên và đánh giá phần còn lại của chuỗi.
  • Có chính xác một ký tự khoảng trắng giữa mỗi từ. Một không gian hàng đầu hoặc dấu vết là chấp nhận được.
  • Đầu ra không phải là trường hợp nhạy cảm.

Chấm điểm

Mã nguồn có ít byte nhất.

Các trường hợp thử nghiệm

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

38
Bất cứ ai quan tâm đến "bài phát biểu golf" nên lưu ý rằng "gấp đôi sáu" sẽ mất nhiều thời gian hơn so với "sáu sáu". Trong tất cả các khả năng số ở đây, chỉ có "ba bảy" lưu các âm tiết.
Tím P

13
@Purple P: Và như tôi chắc chắn bạn biết, 'double-u double-u double-u'> 'world wide web' ..
Chas Brown

11
Tôi bỏ phiếu để thay đổi bức thư đó thành "dub".
Thực phẩm điện tử

8
Tôi biết đây chỉ là một bài tập trí tuệ, nhưng trước mặt tôi có một hóa đơn gas với số 0800 048 1000, và tôi sẽ đọc nó là "oh tám trăm oh bốn tám một nghìn". Việc nhóm các chữ số có ý nghĩa đối với người đọc và một số mẫu như "0800" được xử lý đặc biệt.
Michael Kay

3
@PurpleP Bất cứ ai quan tâm đến sự rõ ràng của lời nói, tuy nhiên, đặc biệt là khi nói qua điện thoại, có thể muốn sử dụng "double 6" vì rõ ràng người nói có nghĩa là hai số sáu và không vô tình lặp lại số 6. Mọi người không phải là robot: P
lỗi và phục hồi Monica

Câu trả lời:


10

05AB1E , 53 52 51 50 49 byte

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

Hãy thử trực tuyến!

Giải trình:

γ                      # 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

1
Oh, Mcũng xem danh sách bên trong khi xác định số nguyên tối đa trên ngăn xếp? Không biết điều đó. Âm thanh như một cái gì đó để nhớ. :)
Kevin Cruijssen

16

Hội 8088, IBM PC DOS, 164 159 156 155 byte

Nhị phân:

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$

Xây dựng và kiểm tra thực thi bằng cách sử dụng xxd -rtừ trên hoặc tải xuống PHONE.COM .

Danh sách chưa được phân loại:

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:

Chuỗi đầu vào được đọc từ phải sang trái để giúp tìm bộ ba dễ dàng hơn. Đầu ra được đẩy lên ngăn xếp x86 để đơn giản hóa việc đảo ngược thứ tự hiển thị và cũng tạo điều kiện sắp xếp lại các từ "gấp đôi" và "gấp ba" trước tên của chữ số.

Nếu chữ số tiếp theo khác với chữ số cuối cùng, tên sẽ được tra cứu trong danh sách các từ và được đẩy lên ngăn xếp. Do không có khái niệm chính thức về "mảng được lập chỉ mục của chuỗi có độ dài thay đổi" trong mã máy, nên danh sách các từ được quét i(chỉ mục của từ) số lần cho dấu phân cách chuỗi ( $) để tìm từ tương ứng. Thật hữu ích, x86 có một cặp hướng dẫn ngắn ( REPNZ SCASBtương tự như memchr()trong C), giúp đơn giản hóa việc này (cảm ơn CISC !).

Nếu chữ số giống với chữ số trước, bộ đếm cho độ dài của "chạy" được tăng lên và tiếp tục lặp lại bên trái trên đầu vào. Khi quá trình chạy kết thúc, tên của chữ số được lấy từ ngăn xếp vì nó sẽ cần được đặt sau "gấp đôi" hoặc "gấp ba" cho mỗi nhóm. Nếu độ dài của đường chạy là số lẻ (và độ dài đường chạy là > 1), tên của chữ số theo sau chuỗi "triple" được đẩy lên ngăn xếp và độ dài đường chạy giảm đi 3. Vì độ dài đường chạy sẽ là chẵn được lặp lại cho "double" cho đến khi độ dài chạy bằng 0.

Khi chuỗi đầu vào đã kết thúc, ngăn xếp được kết xuất với mỗi chuỗi đã lưu được ghi vào màn hình theo thứ tự ngược lại.

Tôi / O:

Một PC DOS độc lập thực thi, nhập từ đầu ra dòng lệnh đến bàn điều khiển.

nhập mô tả hình ảnh ở đây

Tải xuống và kiểm tra PHONE.COM .


repne scasbmemchr(hoặc strchrnếu bạn biết sẽ có một hit), không strstr.
Peter Cordes

CH = 0 khi nhập quy trình được đảm bảo bởi một tiêu chuẩn, hay đó chỉ là những gì phiên bản DOS xảy ra để làm gì? Tôi nhận thấy bạn cho rằng mov cl, byte[si] tương đương với movzx cx, byte [si]. Tôi tự hỏi nếu sử dụng một reg khác, như AH, cho số đếm dec ah / jnzthay vì loopsẽ tiết kiệm bất cứ điều gì từ việc không phải đẩy / pop CX. Có lẽ là không, và bạn không còn bất kỳ reg 16 bit nào cho phép 1 byte dec.
Peter Cordes

1
@PeterCordes, đối với CH=0tôi đi bởi fysnet.net/yourhelp.htmlm , mà đối với bất kỳ bản phát hành hợp lý nào của DOS luôn là zero'd, giống với BX. Suy nghĩ tốt về phần mở rộng bằng không mov, mặc dù về mặt kỹ thuật tôi không nghĩ movzxlà có sẵn trên 808x (giữ cho nền tảng mục tiêu là IBM PC 5150 và tất cả). Tôi loay hoay với tất cả các thanh ghi một cách tốt nhất có thể để lưu các byte, nhưng nếu bạn thấy một cái gì đó tôi có thể bỏ lỡ, xin vui lòng cho tôi biết!
640KB

1
Chính xác hơn là gọi nó là memchrIMO. "Hướng dẫn chuỗi" đặt tên khiến mọi người nghĩ rằng họ làm việc trên các chuỗi C có độ dài ngầm định, nhưng thực sự họ làm việc trên các chuỗi có độ dài rõ ràng như std::stringhoặc bộ đệm. Giống như memcpy, memset(Movs / stos), memchr/ memrchr(repne scas với DF = 0 hoặc 1) và memcmp(repe cmps). Chữ C duy nhất tương đương repe scasstrspnvì tôi không nghĩ có memchức năng đó. Bạn thậm chí có thể mô tả stoswhoặc stosdnhư wmemsetví dụ.
Peter Cordes

1
movzxtốn thêm một byte opcode, và vâng, nó chỉ được giới thiệu với 386. Thật dễ dàng hơn để mô tả thực tế rằng bạn đang thực hiện hợp nhất byte thấp và giả sử nó được mở rộng chính xác. Nếu bạn biết CX hoặc ít nhất CH = 0, thì có để chơi golf luôn đi với movCL. Nhưng bên ngoài việc chơi gôn, các hướng dẫn tải byte của x86 là movzxmovsx: chúng tránh mọi phụ thuộc sai hoặc các shenanigans đăng ký một phần khác. Trên các CPU hiện đại có đích dword, chúng nhanh như mov tải từ.
Peter Cordes

9

05AB1E , 61 56 53 52 51 byte

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

-9 byte nhờ @Grimy .

Hãy thử trực tuyến hoặc xác minh tất cả các trường hợp thử nghiệm .

Giải trình:

γ               # 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)

Xem mẹo 05AB1E này của tôi (phần Làm thế nào để sử dụng từ điển? ) Để hiểu tại sao … ‹¶½¿" double triple"“Šç€µ‚•„í†ìˆÈŒšï¿Ÿ¯¥Š“"oh two three four five six seven eight nine".


1
@Grimy Ah, tất nhiên .. Tôi được thêm vào if(length>=4)trước khi thêm phần còn lại, nhưng tất nhiên nó không phải là cần thiết cho số nguyên kích thước 1,2,3, vì ;Å2¨3ª£sẽ để lại những chuỗi nguyên vẹn (chỉ bọc trong một danh sách chúng tôi san bằng sau khi bản đồ anyway). Cảm ơn đã chú ý! Và mong được thấy câu trả lời của bạn với Åγ. Tôi thực sự có cảm giác phần đầu tiên có thể được thực hiện ngắn hơn nhiều bằng cách nào đó.
Kevin Cruijssen

1
Dg;LàäRvẫn là một byte ngắn hơn āɨšJõKvà tương tự như những gì bạn đã có ban đầu.
Grimmy

1
@Grimy Ah, điều đó thực sự gần với những gì tôi thực sự có ban đầu, tôi thích nó. :) Cảm ơn một lần nữa!
Kevin Cruijssen

1
@Grimy Bạn có thể tự mình tìm thêm một gôn nữa mà tôi đã quên mất .. áthay vì õKở cuối. :)
Kevin Cruijssen

1
Đẹp tìm với á! Đây là 51một số khác . 50 cảm thấy có thể.
Grimmy

7

QuadR , 137 byte SBCS

Trường hợp tiêu đề với một không gian hàng đầu.

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

Hãy thử trực tuyến!

ε nlist (flatten)
¯2↑¨ lấy hai ký tự cuối cùng (đệm ở bên trái với một không gian) của mỗi nhân vật
@ tại các vị trí nơi
(∊∘⎕A) các nhân vật là thành viên của hoa Một lphabet
 trong kết quả của các hoạt động dưới đây PCRE Thay thế ...

(.) bất kỳ ký tự nào được
\1 theo sau bằng
* 0 hoặc nhiều lần hơn, được thay thế bằng kết quả của các bản sau

{…}⍵M "dfn"; M atch của mẫu trên

('OhOneTwoThreeFourFiveSixSevenEightNine'(Cách )⎕A) áp dụng hàm ngầm định ẩn danh sau với chuỗi dài và chữ hoa A lph.us làm đối số bên trái:

 thành viên (của các chữ cái trong chuỗi dài trong bảng chữ cái viết hoa)

 phân vùng (với một phân vùng mới bắt đầu bất cứ khi nào là thành viên

 đối số bên trái (tức là chuỗi dài)

(... )⎕R PCRE R eplace các mẫu sau với những dòng chữ:

⎕D các chữ số từ 0 đến 9

 coi mỗi người như một khuôn mẫu riêng biệt

⍺← gán chức năng thay thế này cho (đối với một lph.usise)

sau đó,

⊃⍵ nhân vật đầu tiên của trận đấu

, như một chuỗi

 áp dụng cho nó

w← gán cái này cho w(cho từ )

' '∊... : nếu không gian là một thành viên của chúng (tức là nếu trận đấu là trống):

 trả về không có gì (trở thành chuỗi rỗng)

 khác

1=≢⍵: nếu một bằng với số lượng ký tự trong trận đấu (tức là độ dài của nó):

⍺⍵ chữ cái đó chữ số

 khác

3=≢⍵: nếu ba bằng tổng số ký tự trong trận đấu (tức là độ dài của nó):

'Triple',w thêm "Triple" cho w ord

 khác

2↓⍵ giảm xuống các chữ số từ trận đấu

 tái diễn về điều đó

w, viết lại từ

'Double', trả trước "Đôi"


6

JavaScript (ES6),  161 160 152  144 byte

Đầu ra bao gồm một không gian hàng đầu duy nhất.

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

Hãy thử trực tuyến!

hoặc Xem mã nguồn được định dạng

Làm sao?

Việc chuyển đổi được xử lý theo ba bước:

  1. thay thế mỗi chữ số bằng từ tiếng Anh tương ứng, trước một khoảng trắng
  2. thay thế từng mẫu "X X"bằng"double X"
  3. thay thế từng mẫu "double X X"bằng"triple X"

Để lưu byte, chúng tôi sử dụng cùng một biểu thức chính quy cho tất cả các bước:

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

hoạt động như sau:

(\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)

Ở bước 1, chúng tôi sử dụng chức năng gọi lại chọn từ đúng từ bảng tra cứu:

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

Ở bước 2, chúng tôi thay thế bằng "$1 double$2" :

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

Ở bước 3, chúng tôi thay thế bằng "triple$2":

  • " (double)( nine)( nine)"" triple nine"



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

Hãy thử trực tuyến!

-1 byte, nhờ Jitse


Đánh tôi lần nữa! Lưu 1 byte như vậy
Jitse

@Jitse, điều đó không hiệu quả 1312;)
TFeld

À, bạn nói đúng!
Jitse

Thế còn cái này thì sao: ['','double ','triple '][n]đến ' eellpbiurotd'[-n:0:-2]168 byte: Hãy thử trực tuyến!
Jitse

Ngoài ra, cũng 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

Hãy thử trực tuyến!

Giải trình:

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>"

1
Cạo một vài byte tắt: 106
Xcali

3

Scala , 213 byte

Hiểu rồi. Bằng cách nào đó, phiên bản đệ quy mà tôi đang cố gắng xây dựng mạnh hơn nhiều so với phiên bản này (mặc dù vẫn đệ quy, nhưng chỉ trong một trường hợp). Hàm flấy như một chuỗi đầu vào số điện thoại và xuất ra ngữ âm của nó với một khoảng trắng ở cuối.

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

Hãy thử trực tuyến!
Chỉnh sửa : -8b cảm ơn DrY Wit!

Scala , 215 byte

Và ở đây có phiên bản khoảng trắng hàng đầu, dài hơn hai byte vì một số lý do (ngay cả với tái cấu trúc lớn).

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

Hãy thử trực tuyến!


2
Bạn có thể lưu 8 byte bằng cách thay thế (o(0)+"").toIntbằng o(0)-48.
Bác sĩ Y Wit

Làm tốt lắm @DrYWit cảm ơn!
V. Courtois

3

PHP , 174 169 166 159 byte

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].' ');

Hãy thử trực tuyến!

Đối với mỗi chữ số tại chỉ mục $ibắt đầu từ 0:

  • Nếu khoảng của cùng một chữ số bắt đầu từ vị trí $ibằng 3, in 'triple 'và thêm 2 vào$i để lần lặp tiếp theo sẽ có 2 chữ số nhảy qua.
  • Nếu khoảng của cùng một chữ số bắt đầu từ vị trí $ibằng hoặc hơn 2 nhưng không phải là 3, hãy in 'double 'và thêm 1 vào$i lặp lại tiếp theo sẽ có 1 chữ số nhảy qua.
  • In từ cho chữ số và dấu cách.
  • $i++.

2

Võng mạc 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

Hãy thử trực tuyến! Đầu ra một không gian hàng đầu. Giải thích: Ban đầu tôi đã thử một regex tự động khớp với 2 hoặc 3 chữ số nhưng cách tiếp cận của @ Arnauld hóa ra là golfer. Giải trình:

+`(.)\1
=$1

Ghép các cặp chữ số giống hệt nhau và thay thế đầu tiên bằng a =. Sau đó lặp lại, để cho một số lẻ, chữ số cuối cùng thứ hai cũng được thay thế bằng a =.

.
 $&

Không gian các chữ số (và =s) ra.

= =
triple

Xử lý trường hợp ba chữ số giống nhau.

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

Thay thế tất cả các ký tự còn lại bằng các từ.


2

Thạch , 59 byte

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

Hãy thử trực tuyến!

Một liên kết đơn âm lấy một chuỗi các ký tự chữ số làm đối số của nó và trả về một chuỗi Jelly gồm các từ được phân tách bằng dấu cách. Khi được gọi là một chương trình đầy đủ, đầu ra ngầm.


2

T-SQL 2017, 238 byte

Đã thêm một số ngắt dòng để làm cho nó dễ đọc

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 @

Dùng thử trực tuyến


2

C ++, 382 byte

Nó không phải là siêu lớp, nhưng ai đó cần phải viết phiên bản C ++. Hàm đệ quy R đi qua chuỗi đầu vào và đếm các giá trị lặp lại. Nếu có nhiều hơn 3 lần lặp lại, nó giả vờ có 2 lần lặp lại, sau đó tua lại và thử lại.

Một vài ký tự nguồn có thể có thể được vắt kiệt bằng #definechính, nhưng tôi chắc chắn một thuật toán tốt hơn có thể vắt kiệt hơn.

#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;
    }
}

và xác minh các trường hợp thử nghiệm:

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

1
Có phần golf thực sự cần #include <sstream>? Hoặc bạn có thể di chuyển nó xuống sau phần chơi gôn cho chức năng kiểm tra? Tôi nghĩ rằng việc gõ std::ostream&ssẽ tốn ít không gian hơn using namespace std;, trừ khi có những nơi khác mà bạn cần a std::.
Peter Cordes


2

Perl 6 , 96 93 byte

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

Hãy thử trực tuyến!

Đây là một khối mã ẩn danh lấy một số và trả về một chuỗi có các chữ số viết hoa, ví dụ 0123 => oh ONE TWO THREEvới một khoảng trắng ở cuối.

Điều này đã bị xóa trong một thời gian cho đến khi tôi tìm ra cách sử dụng ảnh chụp trong một cái nhìn, nhưng nó cần được sửa ngay bây giờ.


1

Màu đỏ , 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]]]

Hãy thử trực tuyến!


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 " "

Hãy thử trực tuyến!


1

Oracle SQL, 578 byte (ở dạng được định dạng)

Giải pháp không ngắn gọn bằng bất kỳ phương tiện nào để đăng nó theo cách được định dạng.

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

Kiểm tra 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

Thủ thuật chính là các chữ số được chuyển đổi thành các từ bằng cách sử dụng các mô hình định dạng của Oracle thay vì các chữ được mã hóa cứng "một" ... "chín".


bất kỳ cơ hội của việc này được chơi golf? có vẻ như bạn có thể loại bỏ một loạt các không gian. Tôi cũng tưởng tượng bạn có thể viết lại WHERE không phải là null thành WHERE s> ''
t-clausen.dk

1
Bạn có thể lưu một vài ký tự bằng cách thay thế những gì sau union allbằng 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]])

Hãy thử trực tuyến!


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

Đảm bảo slà một giá trị chuỗi được xác định trước chỉ được điền bằng các chữ số; đó sẽ là biến được sửa đổi. Kết quả sẽ bao gồm một nhân vật không gian hàng đầu [\u20] .


Chào mừng đến với trang web! Vì Lua có thể nhận đầu vào thông qua các phương thức tiêu chuẩn , nên nó trái với quy tắc bắt sbuộc phải có đầu vào. Bên cạnh đó, bạn đã có một bài viết đầu tiên tốt! Tôi khuyên bạn nên bao gồm một liên kết đến một trang web thử nghiệm trực tuyến, ví dụ: tio.run/#lua để những người khác có thể kiểm tra giải pháp của bạn
caird coinheringaahing

Chào. Biến thể của Lua I đã thử nghiệm trên (Rbx.Lua) không chứa các phương thức nhập liệu, mặc dù hộp cát có các phương thức in, cảnh báo và xuất lỗi.
VisualPlugin Rōblox
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.