話し言葉での電話番号


33

ゴール

数字の電話番号を簡単に言うことができるテキストに変換するプログラムまたは関数を作成します。数字が繰り返される場合、「double n」または「triple n」と読む必要があります。

必要条件

入力

数字のストリング。

  • すべての文字が0〜9の数字であると仮定します。
  • 文字列に少なくとも1つの文字が含まれていると仮定します。

出力

スペースで区切られた、これらの数字の読み上げ方法の単語。

  • 数字を単語に変換します。

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

  • 同じ数字が連続して2回繰り返される場合は、「double number」と書きます。

  • 同じ数字が3回続けて繰り返される場合は、「トリプル番号」と書きます。
  • 同じ数字が4回以上繰り返される場合は、最初の2桁に「double number」を書き込み、残りの文字列を評価します。
  • 各単語の間にちょうど1つのスペース文字があります。単一の先頭または末尾のスペースを使用できます。
  • 出力では大文字と小文字は区別されません。

得点

最小バイトのソースコード。

テストケース

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
「スピーチゴルフ」に興味のある方は、「ダブルシックス」が「シックスシックス」よりも発言に時間がかかることに注意してください。ここでのすべての数値の可能性のうち、「トリプル7」のみが音節を保存します。
パープルP

13
@Purple P:そして、ご存じのとおり、 'double-u double-u double-u'> 'ワールドワイドウェブ' ..
Chas Brown

11
その手紙を「ダブ」に変更することに投票します。
Hand-E-Food

8
これは単なる知的演習であることは知っていますが、目の前に0800 048 1000という番号のガス法案があり、「ああ、八百、四、八、八」と読みます。数字のグループ化は人間の読者にとって重要であり、「0800」などの一部のパターンは特別に扱われます。
マイケルケイ

3
@PurpleP しかし、特に電話で話すとき、スピーチの明瞭さに興味がある人は、「ダブル6」を使用したいと思うかもしれません。人々はロボットではありません:P
謝罪し、モニカを復活させる

回答:


10

05AB1E53 52 51 50 49バイト

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

オンラインでお試しください!

説明:

γ                      # 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
ああ、Mスタックの最大整数を決定するときにリストの内側も調べますか?それを知らなかった。覚えておくべきことのように聞こえます。:)
ケビンクルーッセン

16

8088アセンブリ、IBM PC DOS、 164 159 156 155バイト

バイナリ:

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$

xxd -r上記から実行ファイルをビルドしてテストするか、PHONE.COMをダウンロードします。

組み立てられていないリスト:

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:

入力文字列は、トリプルを見つけやすくするために右から左に読み取られます。出力はx86スタックにプッシュされ、表示順序の反転が簡単になり、数字の名前の前に「ダブル」と「トリプル」の単語を再配置しやすくなります。

次の数字が最後の数字と異なる場合、名前は単語のリストで検索され、スタックにプッシュされます。マシンコードには「可変長文字列のインデックス付き配列」という正式な概念がないため、対応する単語を見つけるiために、文字列区切り文字($)の単語リストが(単語のインデックス)回スキャンされます。便利なことに、x86には2つの短い命令(CにREPNZ SCASB似ていますmemchr())があり、これが簡単になります(CISCに感謝!)。

数字が前の数字と同じ場合、「実行」の長さのカウンターがインクリメントされ、入力で左方向にループし続けます。実行が終了すると、各グループの「ダブル」または「トリプル」の後に配置する必要があるため、数字の名前はスタックから取得されます。ランの長さが奇数の場合(およびランの長さが> 1)、文字列「トリプル」が後に続く数字の名前がスタックにプッシュされ、ランの長さが3減ります。ランの長さが偶数になるため、ステップランレングスが0になるまで「ダブル」に対して繰り返されます。

入力文字列が最後に達すると、保存された各文字列が逆の順序で画面に書き込まれ、スタックがダンプされます。

I / O:

スタンドアロンPC DOS実行可能ファイル、コマンドライン出力からコンソールへの入力。

enter image description here

PHONE.COMをダウンロードしてテストします


repne scasbあるmemchr(またはstrchr、ないあなたは、ヒットがあるように起こっている知っている場合)strstr
ピーターコーデス

プロセスエントリのCH = 0は標準によって保証されていますか、それとも一部のDOSバージョンで行われていることですか?あなたはそれmov cl, byte[si] がに等しいと仮定していることに気付きますmovzx cx, byte [si]。CXをプッシュ/ポップする必要がないのでAH、カウントのdec ah / jnz代わりにのような別のregを使用すると、loop何かを節約できるのでしょうか。おそらくそうではなく、1バイトを許可する16ビットregsが残っていませんdec
ピーターコーデス

1
@PeterCordes、CH=0私にとってはfysnet.net/yourhelp.htmであり、DOSの合理的なリリースでは常にゼロになりBXます。mov技術的にはmovzx808x(ターゲットプラットフォームをIBM PC 5150とすべてに維持)で利用できるとは思わないが、ゼロ拡張についてはよく考えた。バイトを節約するために最善を尽くして、すべてのレジスタをいじりましたが、見逃した可能性のあるものがあれば、教えてください!
640KB

1
memchrIMO と呼ぶ方がより正確です。「文字列命令」という名前は、暗黙の長さのC文字列で作業していると考えるように人々を誤解させますが、実際にはstd::string、バッファのような明示的な長さの文字列で機能します。のようにmemcpymemset(movs / stos)、memchr/ memrchr(DF = 0または1でmemcmpscasを繰り返します)、および(繰り返しcmps)。Cに相当するのrepe scasは、そのためstrspnmem関数がないと思うからです。あなたも記述することができますstoswまたはstosdとしてwmemset挙げられます。
ピーターコーデス

1
movzx余分なオペコードバイトが必要です。もちろん386でのみ導入されました。低バイトマージを実行しており、正しくゼロ拡張されていると仮定することで、入力しやすくなりました。CXまたは少なくともCH = 0がわかっている場合は、ゴルフの場合は常にmovCLを使用します。しかし、ゴルフの外では、x86のgo-to byte-load命令はmovzxand movsxです。これらは、誤った依存関係やその他の部分的なレジスターの回避を回避します。dword宛先を備えた最新のCPUでは、dwordがmov ロードするのと同じくらい高速です。
ピーターコーデス

9

05AB1E61 56 53 52 51 バイト

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

@Grimyのおかげで-9バイト。

オンラインそれを試してみたり、すべてのテストケースを確認してください

説明:

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

この05AB1Eのヒント(「辞書の使用方法」セクション)を参照して、… ‹¶½¿is " double triple"および“Šç€µ‚•„í†ìˆÈŒšï¿Ÿ¯¥Š“is を理解してください"oh two three four five six seven eight nine"


1
@Grimy Ah、もちろん.. if(length>=4)残りを追加する前にを追加しましたが、もちろん、sizeの整数には必要ありません。文字列がそのまま残る1,2,3ためです;Å2¨3ª£(マップの後にフラット化するリストにラップするだけです)。気づいてくれてありがとう!そして、あなたの答えを楽しみにしていますÅγ。どういうわけか、最初の部分はもっと短くできると感じました。
ケビンクルーッセン

1
Dg;LàäRは、まだ1バイトより短く、āɨšJõK元々持っていたものにずっと似ています。
グリムミー

1
@Grimyああ、それは私が最初に実際に持っていたものに本当に閉じている、私はそれが好きです。:) 再度、感謝します!
ケビンクルーッセン

1
@Grimy 最後áõKではなく、私が忘れていたもう1つのゴルフを自分で見つけることができました。:)
ケビンクルーッセン

1
素敵な発見á!ここだ51別のものを。50は可能だと感じています。
グリムミー

7

QuadR、137 バイトSBCS

先頭にスペースがあるタイトルケース。

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

オンラインでお試しください!

ϵ nlist(平坦化)
¯2↑¨ は、各文字の最後の2文字(左側にスペースを入れてパディング)を取得します
@ 。
(∊∘⎕A)  文字が大文字のメンバーであるAの lphabet
 PCREの下操作を交換した結果に...

(.) 任意のキャラクター
\1 それ自体が
* ゼロ回以上続くは、次の結果に置き換えられます…

{…}⍵M 「dfn」; あるMの上記パターンのATCH

('OhOneTwoThreeFourFiveSixSevenEightNine'()⎕A)  長い文字列と大文字のA lphabetを左引数として使用して、次の匿名暗黙関数を適用します。

 (大文字のアルファベットの長い文字列の文字の)メンバーシップ

 パーティション(is-a-memberのときはいつでも新しいパーティションで始まる

 左引数(つまり、長い文字列)

()⎕R PCRE Rは、これらの単語で次のパターンを置き換えます。

⎕D 0から9の数字

 それぞれを個別のパターンとして扱う

⍺← この置換機能を割り当てるために( lphabetise)

その後、

⊃⍵ マッチの最初の文字

, 文字列として

 適用する する

w← これをw単語に対して

' '∊: スペースがそのメンバーである場合(つまり、マッチが空だった場合):

 何も返さない(空の文字列になる)

 そうでなければ、

1=≢⍵: 一致する文字の集計(つまりその長さ)に等しい場合:

⍺⍵ その数字をアルファベット順にする

 そうでなければ、

3=≢⍵: 3が一致する文字の集計(つまりその長さ)に等しい場合:

'Triple',wwに  「トリプル」を追加します ORD

 そうでなければ、

2↓⍵ マッチから数字にドロップ

 その上で再帰

w, 言葉を付け加える

'Double', 「Double」を追加


6

JavaScript(ES6)、 161 160 152  144バイト

出力には、単一の先行スペースが含まれます。

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

オンラインでお試しください!

または フォーマットされたソースコードを見る

どうやって?

変換は3つのステップで処理されます。

  1. 各数字を、スペースが前にある対応する英語の単語に置き換えます
  2. 各パターンを置き換える "X X""double X"
  3. 各パターン"double X X""triple X"

バイトを節約するために、すべてのステップに同じ正規表現を使用します。

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

次のように機能します。

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

ステップ1では、ルックアップテーブルから正しい単語を選択するコールバック関数を使用します。

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

ステップ2では、次のものに置き換え"$1 double$2"ます。

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

ステップ3で、次のものに置き換え"triple$2"ます。

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



3

パイソン2171の 169 168バイト

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

オンラインでお試しください!

-1バイト、Jitseのおかげ


もう一度私を打ちます!保存1バイトのようなので、
Jitse

@Jitse、それは動作しません1312;)
TFeld

ああ、あなたは正しい!
Jitse

どのようにこの1について次のようにします['','double ','triple '][n]' eellpbiurotd'[-n:0:-2]168バイトのために:オンラインそれをお試しください!
Jitse

または、168バイト
Jitse

3

Perl -p 5、111バイト

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

オンラインでお試しください!

説明:

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
数バイト
削り取った

3

スカラ、213バイト

とった。どういうわけか、私が構築しようとした再帰バージョンは、このバージョンよりも非常に冗長でした(ただし、再帰的ですが、1つの場合のみ)。関数fは、入力文字列として電話番号を取得し、末尾の空白を含む音声学を出力します。

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

オンラインでお試しください!
編集:Dry Y Witのおかげで-8b

Scala、215バイト

そしてここに、何らかの理由で(大規模なリファクタリングを行ったとしても)2バイト長い、主要な空白バージョンが登場します。

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

オンラインでお試しください!


2
あなたは置き換えることによって、8つのバイトを保存することができ(o(0)+"").toInto(0)-48
Yウィット博士

@DrYWitありがとうございます!
V.クルトワ

3

PHP174の 169 166 159バイト

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

オンラインでお試しください!

$i0から始まるインデックスの各桁に対して:

  • の位置から始まる同じ数字のスパンが$i3に等しい場合、'triple '2を出力して追加します$i、次の反復で2桁ジャンプようにします。
  • の位置から始まる同じ桁のスパンが$i2以上であるが3ではない場合、'double '1を印刷して追加し$i、次の反復で1桁ジャンプします。
  • 数字とスペースの単語を出力します。
  • $i++

2

Retina 0.8.2、105バイト

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

オンラインでお試しください!先行スペースを出力します。説明:私はもともと、2桁または3桁に自動的に一致する正規表現を試しましたが、@ Arnauldのアプローチはゴルファーであることが判明しました。説明:

+`(.)\1
=$1

同一の数字のペアを一致させ、最初の数字をaに置き換え=ます。次に繰り返します。奇数の場合、最後から2番目の桁もに置き換えられ=ます。

.
 $&

数字(および=s)を空白にします。

= =
triple

同一の3桁のケースを処理します。

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

残りのすべての文字を単語に置き換えます。


2

ゼリー、59バイト

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

オンラインでお試しください!

引数として数字の文字列を取り、スペースで区切られた単語のゼリー文字列を返すモナドリンク。フルプログラムとして呼び出されると、暗黙的に出力されます。


2

T-SQL 2017、238バイト

読みやすくするために改行を追加しました

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 @

オンラインで試す


2

C ++、382バイト

それは賢いことではありませんが、誰かがC ++バージョンを書く必要がありました。再帰関数Rは入力文字列を調べて、繰り返される値をカウントします。繰り返しが3回以上ある場合は、繰り返しが2回行われたふりをしてから、巻き戻して再試行します。

おそらく#defineメジャーでさらにいくつかのソース文字を絞り出すことができますが、より良いアルゴリズムがもっと絞り出すことができると確信しています。

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

テストケースの検証:

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
ゴルフ部品は実際に必要#include <sstream>ですか?それとも、テスト機能のためにゴルフパートの後にそれを下に移動できますか?あなたが必要とする他の場所がない限り、タイピングstd::ostream&sはより少ないスペースを取ると思います。using namespace std;std::
ピーターコーデス


2

Perl 6の96の 93バイト

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

オンラインでお試しください!

これは、数字を受け取り、大文字の数字を含む文字列を返す匿名コードブロックです0123 => oh ONE TWO THREE。たとえば、末尾にスペースが1つあります。

先読みでキャプチャを使用する方法が見つかるまで、これはしばらくの間削除されましたが、今は修正する必要があります。




1

Oracle SQL、578バイト(フォーマットされた形式)

解決策は決して簡潔ではないので、フォーマットされた方法で投稿してください。

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

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

主なトリックは、ハードコードされたリテラル「one」...「nine」の代わりにOracle形式モデルを使用して数字を単語に変換することです。


これがゴルフにかけられる可能性はありますか?たくさんのスペースを削除できるようです。sがにヌルでない場合、私はまた、あなたが書き換えることができます想像ここでS>「」
t-clausen.dk

1
あなたは後何置き換えることによって、いくつかの文字を保存することができますunion allselect regexp_replace(s,case when length(regexp_substr(s, '(.)(\1)+')) = 3 then '^...' else '^(.)\1|^.' end) from r
スティーブカス


1

(Roblox)Lua 5.1、166 バイト

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

s数字のみが入力された定義済みの文字列値であることを確認してください。それが変更される変数になります。結果には、先頭のスペース 文字が含まれます[\u20]


サイトへようこそ!Luaは標準メソッドを介して入力を取得できるためs、すでに入力を取得する必要があるというルールに反しています。それとは別に、良い最初の投稿があります!他の人がソリューションをテストできるように、オンラインテストサイト(例:tio.run/#lua)へのリンクを含めることをお勧めします
caird coinheringaahing

こんにちは。テストしたLua Iのバリアント(Rbx.Lua)には入力メソッドが含まれていませんが、サンドボックスには印刷、警告、エラーの出力メソッドがあります。
VisualPluginRōblox
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.