以下の条件に従って数値を出力します。
Fizz
を出力。Buzz
を出力。FizzBuzz
を出力。$ flc '1~17|&(_%3?E:"Fizz",_%5?E:"Buzz")||_'
# 1
# 2
# Fizz
# 4
# Buzz
# Fizz
# 7
# 8
# Fizz
# Buzz
# 11
# Fizz
# 13
# 14
# FizzBuzz
# 16
1~17
は1以上17未満の整数を順番に生成するストリームです。
|
は左辺のストリームの各要素について、右辺を評価する演算子です。
&
は値の前に付けるとその値を文字列化する演算子です。
_
は |
演算子の右辺で使用すると現在の要素を取得できる変数です。
%
は左辺の値を右辺で割った余りを返す演算子です。
a:b?c
と書くと、 a
が真の場合に b
を、偽の場合に c
を返します。
E
は空のストリームを表す定数です。
,
はストリームや値を連結したストリームを返す演算子です。
||
は左辺が真の場合に左辺の値を、偽の場合に右辺の値を返す演算子です。空文字列は偽として扱われます。
_%3?E:"Fizz"
は、値が3で割り切れた場合に空ストリームを、そうでない場合に文字列 Fizz
を得ます。
同様に、 _%5?E:"Buzz"
は、値が5で割り切れた場合に空ストリームを、そうでない場合に文字列 Buzz
を得ます。
ここで、 _%3?E:"Fizz",_%5?E:"Buzz"
は _
の値によって以下の値を取ります。
Fizz
Buzz
Fizz
, Buzz
それを &
演算子で文字列として連結(空ストリームの場合は空文字列)します。
その結果が空文字列だった場合、元の値を返します。
これを1から順番に繰り返し行います。
$ flc '
fib := n -> n < 2 ? n : fib(n - 1) + fib(n - 2)
fib(10)
'
# 55
$ flc '
quicksort := list -> $#list < 2 ? list : (
pivot := list.0
high := [list() >> FILTER [ _ => _ > pivot ]]
middle := [list() >> FILTER [ _ => _ == pivot ]]
low := [list() >> FILTER [ _ => _ < pivot ]]
quicksort(low) + middle + quicksort(high)
)
quicksort([3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5])
'
# [1;1;2;3;3;4;5;5;5;6;9]
$ flc '
m := a, b -> (
ai := 0
bi := 0
[0 ~ $#a + $#b | (
ai != $#a && (bi == $#b || a(ai) < b(bi)) ? (
v := a(ai)
ai = ai + 1
v
) : (
v := b(bi)
bi = bi + 1
v
)
)]
)
ms := l -> $#l < 2 ? l : (
c := FLOOR($#l / 2)
m(
ms(l[0 ~ c])
ms(l[c ~ $#l])
)
)
ms([3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5])
'
# [1;1;2;3;3;4;5;5;5;6;9]
$ flc '
edit_distance := a, b -> (
dp := [0 .. $#a + 1 | [0 .. $#b + 1 | 0]]
0 .. $#a | i => 0 .. $#b | j => (
dp(i + 1)(j + 1) = a(i) == b(j)
? dp(i)(j)
: 1 + MIN(
dp(i )(j ),
dp(i + 1)(j ),
dp(i )(j + 1),
)
)
# Output Table
[
["", "", b()]
0 ~ $#dp | i => [a.(i - 1) ?: "", dp(i)()]
]() | OUT << _() | "$%2s(_)" >> JOIN[""]
dp(-1)(-1)
)
edit_distance("kitten"; "sitting")
'
# s i t t i n g
# 0 0 0 0 0 0 0 0 0
# k 0 1 1 1 1 1 1 1 1
# i 0 1 1 2 2 1 2 2 2
# t 0 1 2 1 2 2 2 3 3
# t 0 1 2 2 1 2 3 3 4
# e 0 1 2 3 2 2 3 4 4
# n 0 1 2 3 3 3 2 3 4
# 0 1 2 3 4 4 3 3 3
# 3
$ flc -q '
is_prime := n ->
n < 2 ? FALSE
: n == 2 ? TRUE
: !(2 .. FLOOR(SQRT(n)) | n %% _)
0 .. 4 | x => (
OUT << 0 .. 9 | y => x * 10 + y | n => "$%4s(is_prime(n) ? n : "-")" >> JOIN[""]
)
'
# - - 2 - - 5 - 7 - -
# - 11 - 13 - - - 17 - 19
# - - - 23 - - - - - 29
# - 31 - - - - - 37 - -
# - 41 - 43 - - - 47 - -
横40マス、縦40マス、待機時間200ミリ秒でライフゲームを実行します。
パフォーマンスのためにjvm版で起動します。
$ FLC_ENGINE=jvm flc -q '
LifeGame := {
init : this -> this.b = [0 ~ this.h | [0 ~ this.w | RAND(2)]]
get : this, x, y -> this.b(y % this.h)(x % this.w)
neighbors: this, x, y -> -1 .. 1 | dx => -1 .. 1 | dy => dx == 0 && dy == 0 ? 0 : this::get(x + dx; y + dy) >> SUM
get_next : this -> [0 ~ this.h | y => [0 ~ this.w | x => this::neighbors(x; y) | +(this::get(x; y) ? _ == 2 || _ == 3 : _ == 3)]]
step : this -> this.b = this::get_next()
`&_` : this -> this.b() | l => (l() | _ ? "[]" : " " >> JOIN[""]) >> JOIN["\n"]
}
lifeGame := LifeGame{w: +ARGS.0; h: +ARGS.1}
lifeGame::init()
OUT << "$lifeGame\n$("--" * +ARGS.0)"
1 .. 10000 | (
lifeGame::step()
OUT << "$lifeGame\n$("--" * +ARGS.0)"
SLEEP(+ARGS.2)
)
' 40 40 200
WINDOW.document::getElementById("output").outerHTML = %>
<div id="output" style="border-collapse: collapse; height: 100%; overflow-y: scroll;">
<style>
#output td, #output th {
width: 3ex;
height: 3ex;
border: 1px solid black;
text-align: center;
}
</style>
<table>
<%= 1 .. 9 | x => %>
<tr>
<%= 1 .. 9 | y => %>
<td><%= x * y %></td>
<% %>
</tr>
<% %>
<table/>
</div>
<%
width := 200
height := 200
by_id := id -> WINDOW.document::getElementById(id)
by_id("output").outerHTML = %><div id="output" class="box"></div><%
by_id("output").innerHTML = %><canvas id="canvas" width="<%= width %>" height="<%= height %>" style="border: 1px solid #888888;"><%
ctx := by_id("canvas")::getContext("2d")
0 .. 10000000 | i => (
SLEEP(20)
ctx::resetTransform()
ctx::clearRect(0; 0; 200; 200)
ctx::translate(100; 100)
ctx::rotate(i / 180 * 4)
ctx::translate(-100; -100)
ctx.fillStyle = 'blue'
ctx::fillRect(50; 50; 100; 100)
ctx.strokeStyle = 'red'
ctx.lineWidth = 4
ctx::strokeRect(50; 50; 100; 100)
)