変形Fizz-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の文法自体ないんで普通に。
see: 玄箱でアセンブリ
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 ;
|





raynstard
#3758()
Rating0/2=0.00
[ reply ]