challenge 変形Fizz-Buzz問題

どもraynstardです。
どちらにしようか迷いましたが発想の元ネタがUIさんの投稿からなので
こちらに投稿してみます。
--------------
以下の仕様を満たす文字列を
20行出力するプログラムを作成してください。

1. 1行の出力は「<行番号> ':' <メッセージ>」であること。
2. 行番号が 3の倍数であるとき、メッセージは「Fizz」であること
3. 行番号が 5の倍数であるとき、メッセージは「Buzz」であること
4. 行番号が 3の倍数かつ5の倍数であるとき、メッセージは「FizzBuzz」であること
5. 上記に記した条件以外のメッセージについては「hoge」であること
6. 条件分岐する場合、if文のみが使用でき、
   かつ、論理式が成立した場合の処理のみが記述できます。
#アセンブリなどifがなければif以外でもかまわないです。(意味が同じならば)

というわけでこの問題はFizz-Buzz問題をelseなしならどう書く?という問題です。

出力例:
 1:hoge
 2:hoge
 3:Fizz
 4:hoge
 5:Buzz
 6:Fizz
 7:hoge
 8:hoge
 9:Fizz
10:Buzz
11:hoge
12:Fizz
13:hoge
14:hoge
15:FizzBuzz
16:hoge
17:hoge
18:Fizz
19:hoge
20:Buzz

Posted feedbacks - Other

出題意図が今一不明ですが,else を使うなというだけなら,以下のように書けるが,ifすら使う必要がないというkkobayashiさんの意見はごもっとも。
else を使わないというのは,なんの制約にもならないと思うのだが。。。
1
2
3
4
5
6
7
for (i in 1:20) {
    str <- "hoge"
    if (i %% 3 == 0) str <- "Fizz"
    if (i %% 5 == 0) str <- "Buzz"
    if (i %% 15 == 0) str <- "FizzBuzz"
    cat(i, ":", str, "\n")
}

Mac OS X (PowerPC 32bit) アセンブリで。else if, elseの文法自体ないんで普通に。

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
        ;; Mac OS X (PowerPC 32bit)
        ;; % as -o fizzbuzz.o fizzbuzz.s && gcc fizzbuzz.o -o fizzbuzz
        .machine ppc
        .globl _main

_main:
        li      r6, 1           ; 行番号

_print_line:
        li      r9, 0           ; Fizz出力フラグ

        ;; 行番号の出力
        li      r4, hi16(line)
        addi    r4, r4, lo16(line)
        li      r5, hi16(line_len)
        addi    r5, r5, lo16(line_len)

        ;; 行番号の xx を書き換える
        cmpli   cr7, r6, 10
        blt     cr7, _replace_one_digit

        ;; 二桁の行番号
        ;; 一桁目を求める
        li      r8, 10          ; 10で割った商を求める
        divwu   r7, r6, r8
        addi    r7, r7, 48      ; 数字のASCIIコードを求める
        stb     r7, 0(r4)       ; 文字列の先頭を書き換える
        addi    r4, r4, 1       ; 文字列のポインタを進める
        
        ;; 二桁目を求める
        li      r8, 10          ; 10で割った余りを求める
        divwu   r7, r6, r8      ; 割って(=商)
        mullw   r7, r7, r8      ; かけて(商*除数)
        subf    r7, r7, r6      ; 引く(被除数-商*除数)
        addi    r7, r7, 48      ; 数字のASCIIコードを求める
        stb     r7, 0(r4)       ; 文字列の先頭を書き換える
        subi    r4, r4, 1       ; 文字列のポインタを戻しておく  
        b       _print_line_num

_replace_one_digit:
        li      r7, 32          ; ASCIIコード: ' '
        stb     r7, 0(r4)
        addi    r4, r4, 1
        addi    r7, r6, 48      ; 数字のASCIIコードを求める
        stb     r7, 0(r4)
        subi    r4, r4, 1       ; 文字列のポインタを戻しておく

_print_line_num:
        bl      _print_str

_print_msg:
        ;; 3の倍数
        li      r8, 3
        divwu   r7, r6, r8
        mullw   r7, r7, r8
        subf    r7, r7, r6
        cmpli   cr7, r7, 0
        bne     cr7, _print_msg2

        ;; Fizz を出力
        li      r9, 1           ; Fizz出力済みフラグ
        li      r4, hi16(fizz)
        addi    r4, r4, lo16(fizz)
        li      r5, hi16(fizz_len)
        addi    r5, r5, lo16(fizz_len)
        bl      _print_str
        
_print_msg2:
        ;; 5の倍数
        li      r8, 5
        divwu   r7, r6, r8
        mullw   r7, r7, r8
        subf    r7, r7, r6
        cmpli   cr7, r7, 0
        bne     cr7, _print_hoge
        
        ;; Buzz を出力
        li      r4, hi16(buzz)
        addi    r4, r4, lo16(buzz)
        li      r5, hi16(buzz_len)
        addi    r5, r5, lo16(buzz_len)
        bl      _print_str
        b       _print_term

_print_hoge:
        ;; Fizz を出力済みなら飛ばす
        cmpli   cr7, r9, 0
        bne     cr7, _print_term
        
        ;; hoge を出力
        li      r4, hi16(hoge)
        addi    r4, r4, lo16(hoge)
        li      r5, hi16(hoge_len)
        addi    r5, r5, lo16(hoge_len)
        bl      _print_str

_print_term:
        ;; 改行の出力
        li      r4, hi16(lf)
        addi    r4, r4, lo16(lf)
        li      r5, hi16(lf_len)
        addi    r5, r5, lo16(lf_len)
        bl      _print_str
        
        ;; 20行分繰り返す
        addi    r6, r6, 1
        cmpli   cr7, r6, 20
        ble     cr7, _print_line
        b       _exit

;; 文字列を出力する
;; r4 に文字列のアドレスを、r5 に文字列の長さをセットしておく
_print_str:
        ;; スタックに退避
        stwu    r6, -4(r1)

        ;; sys_write()
        li      r3, 1           ; 標準出力
        li      r0, 4           ; sys_write
        sc                      ; 呼び出し

        ;; スタックから復帰
        lwz     r6, 0(r1)
        addi    r1, r1, 4

        ;; サブルーチンから戻る
        blr

_exit:
        li      r3, 0
        li      r0, 1           ; sys_exit
        sc


        .data
        .align 2

line:
        ;; xx の箇所は出力時に書き換える
        .asciz  "xx: "
        line_len = 4

fizz:
        .asciz  "Fizz"
        fizz_len = . - fizz - 1
        
buzz:
        .asciz  "Buzz"
        buzz_len = . - buzz - 1

hoge:
        .asciz  "hoge"
        hoge_len = . - hoge - 1

lf:
        .asciz  "\n"
        lf_len = 1

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
USING: kernel math math.parser io sequences ;

20 [
  1 + dup dup number>string write ":" write
  3 mod 0 =
  swap 5 mod 0 =
  2dup swap
  [ "Fizz" write ] [ ] if
  [ "Buzz" write ] [ ] if
  or not [ "hoge" write ] [ ] if
  nl
] each

ActiveBasic、どう書く?org初のはずです。バージョン4.24を使いましたが、特にバージョン依存の機能は使っていないはずです。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
#prompt 'N88風コンソール窓を使う指定

Dim s As String
Dim i As Long
For i = 1 To 20
    s = ""
    If i Mod 3 = 0 Then
        s = "Fizz"
    End If

    If i Mod 5 = 0 Then
        s = s + "Buzz"
    End If

    If s = "" Then
        s = "hoge"
    End If

    Print Str$(i) +  ":" + s
Next

Forth でFizzBuzzしてみました。数字の後にスペースが入ってしまってしまうのは仕様です。
Not Equal使っているので微妙ですが、全部スタックなのでご容赦願います。

pForthでの実行結果:
> 20 FizzBuzz
1 :hoge
2 :hoge
3 :Fizz
4 :hoge
5 :Buzz
6 :Fizz
7 :hoge
8 :hoge
9 :Fizz
10 :Buzz
11 :hoge
12 :Fizz
13 :hoge
14 :hoge
15 :FizzBuzz
16 :hoge
17 :hoge
18 :Fizz
19 :hoge
20 :Buzz
1
2
3
4
5
6
7
8
: FizzBuzz ( n -- )
1 + 1 DO
  I DUP . ." :" 
  DUP 3 mod 0 = IF ." Fizz" THEN
  DUP 5 mod 0 = IF ." Buzz" THEN
  DUP 3 mod 0 <> IF DUP 5 mod 0 <> IF ." hoge" THEN THEN
  CR
LOOP ;

前のコードでは、スタックにゴミが残ってたりIF文が重なってたりと、微妙だったので修正版を。 出力結果は同じです。

1
2
3
4
5
6
7
8
: FizzBuzz ( n -- )
1 + 1 DO
  I DUP . ." :" 
  DUP 3 MOD 0 = IF ." Fizz" THEN
  DUP 5 MOD 0 = IF ." Buzz" THEN
  DUP 3 MOD 0 <> SWAP 5 MOD 0 <> AND IF ." hoge" THEN
  CR
LOOP ;

Index

Feed

Other

Link

Pathtraq

loading...