LoginSignup
1
1

More than 5 years have passed since last update.

「レッスンは何曜日?」をFactorで(横へな21)

Last updated at Posted at 2014-06-03

レッスンは何曜日?」をFactorでやってみました。他の皆様による実装は 第21回オフラインリアルタイムどう書くの問題 から辿れます。

次のような方針で解きました。

  1. 各クラスについて最優先で希望している社員を配属する
  2. 各クラスを先頭4人だけに絞る
  3. 配属され先頭4人に入った人をリストから削除する
  4. 未配属の人の希望クラスの1番目を消し、2番目を1番目に移動する
  5. 全員の希望クラスがなくなるまで、1の手順に戻って繰り返す
21lesson.factor
USING: kernel sequences sequences.deep math math.order math.parser
       arrays splitting assocs sorting ;
IN: 21lesson

! 希望リストから配属候補を求める
: wish-list>candidate ( wish-list -- candidate )
    { 1 2 3 4 5 } swap [
        [ second first over = ] filter
        [ first ] map swap drop
    ] curry map ;

! 先頭4つだけにする
: only4 ( seq -- seq ) dup length 4 min head ;

! 配属リストに候補を追加する
: append-candidate-to-assigned ( assigned candidate -- assigned' )
    [ append only4 ] 2map ;

! 配属された社員を希望リストから削除する
: delete-assigned-from-wish-list ( assigned wish-list -- wish-list' )
    swap flatten [ swap first swap index not ] curry filter ;

! 希望リストの順位を繰り上げる
: shift-wish-list ( wish-list -- wish-list' )
    [ dup first swap second rest { } 2sequence ] map ;

! 最も高い希望を配属する
: assign-first-wish ( assigned wish-list -- assigned' wish-list' )
    [ wish-list>candidate append-candidate-to-assigned ] keep
    dupd delete-assigned-from-wish-list
    shift-wish-list ;

! 配属する
: assign-wish ( wish-list -- assigned )
    { { 0 { 0 0 0 0 0 } } } append
    5 { } <array> swap
    5 [ assign-first-wish ] times
    drop ;

! 入力文字列を希望リストに変換する
: >wish-list ( str -- wish-list )
    "|" split [ "_" split [ first string>number ]
        [ second [ digit> ] { } map-as ] bi { } 2sequence ] map ;

! 配属リストを文字列に変換する
: assigned>string ( assigned -- str )
    { 1 2 3 4 5 } swap zip
    [ second length 0 = not ] filter
    [
        dup first number>string "_" append
        swap second natural-sort
        [ number>string ] map ":" join append
    ] map "|" join ;

! 解く
: solve ( str -- str ) >wish-list assign-wish assigned>string ;

Factorを始めました。自分で書いたコードなのに数日経ったら読めません (^^;)

Factorは連鎖性プログラミング言語です。多くのプログラミング言語が func(arg1, arg2)(func arg1 arg2) という語順なのに対して、Forthを始めとする連鎖性言語は arg1 arg2 func という語順で書きます。通常は変数を使わず、引数をスタックに積んで関数(ワード)を呼び出すと、結果がスタックに積まれて返ってきます。JVM(Java仮想マシン)のニーモニックを直接書いている雰囲気ですが、クォーテーション(無名関数)を使ったmapやfilterなど、関数型言語に似ている部分があります。

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1