今更でもズンドコキヨシ (js/VB/HSP/Lisp/Excel)

  • 0
    いいね
  • 0
    コメント

    元ネタ
    まとめ
    時期遅れって言えないレベルですが、今更マイブームになっているので数種類実装してみました。
    レギュレーションとしてズンズンズンズンズンドコは無しにしています。

    文字列比較 js/VB

    JavaScript

    kiyoshi.js
    console.log(kiyoshi());
    
    function kiyoshi(){
        const zundoko=["ズン","ドコ"];
        const exit_kiyoshi="キ・ヨ・シ!"
        const zdchk="00001";
        var rec="";
        for(;;){
            var zd=Math.floor(Math.random()*zundoko.length);
            process.stdout.write(zundoko[zd]);
            rec+=zd;
            if(zdchk[0]==rec.slice(-(zdchk.length+1))[0] && zdchk==(rec).slice(-zdchk.length)){
                return exit_kiyoshi;
            }
        }
    }
    

    VB.net

    kiyoshi.vb
    Imports System
    Imports System.Console
    Imports Microsoft.VisualBasic
    
    Module Program
        Sub Main()
            WriteLine(kiyoshi())
        End Sub
    
        Function kiyoshi() As String
            Dim rand As New Random()
            Dim zundoko As String()={"ズン","ドコ"}
            Dim exit_kiyoshi As String="キ・ヨ・シ!"
            Dim zdchk="00001"
            Dim rec As String=""
            Do
                Dim zd As Long=rand.Next(zundoko.Length)
                Write(zundoko(zd))
                rec &= zd
                If zdchk(0)<>Right(rec,zdchk.Length+1)(0) And zdchk=Right(rec,zdchk.Length) Then
                    Return exit_kiyoshi
                End If
            Loop
        End Function
    End Module
    

    一番最初に書いた型だったけど値を配列に保持してないのでレギュ違反気味。
    オンライン実行環境: JavaScript, VB.net

    配列スライド js/VB

    JavaScript

    kiyoshi.js
    console.log(kiyoshi());
    
    function kiyoshi(){
        const zundoko=["ズン","ドコ"];
        const exit_kiyoshi="キ・ヨ・シ!"
        const zdchk=[0,0,0,0,1];
        var stk=new Array(zdchk.length);
        for(;;){
            var zd=Math.floor(Math.random()*zundoko.length);
            process.stdout.write(zundoko[zd]);
            stk.push(zundoko[zd])
            var stk0=stk.shift();
            if(stk0!=zundoko[zdchk[0]] && stk.join()==zdchk.map(val=>zundoko[val]).join()){
                return exit_kiyoshi;
            }
        }
    }
    

    VB.net

    kiyoshi.vb
    Imports System
    Imports System.Console
    Imports System.Collections.Generic
    
    Module Program
        Sub Main()
            WriteLine(kiyoshi())
        End Sub
    
        Function kiyoshi() As String
            Dim rand As New Random()
            Dim zundoko As String()={"ズン","ドコ"}
            Dim exit_kiyoshi As String="キ・ヨ・シ!"
            Dim zdchk As String()={0,0,0,0,1}
            Dim stk As New LinkedList(Of String)(New String(5-1){})
            Do
                Dim zd As Long=rand.Next(zundoko.Length)
                Write(zundoko(zd))
                stk.AddLast(zundoko(zd))
                Dim stk0 As String=stk.First.Value
                stk.RemoveFirst()
                If stk0<>zundoko(zdchk(0)) And String.Join("",stk)=String.Join("",Array.ConvertAll(zdchk,Function(val) zundoko(val))) Then
                    Return exit_kiyoshi
                End If
            Loop
        End Function
    End Module
    

    pushしてshiftすれば1つ分スライドするよねっていう発想。
    .Netの配列にはこの機能が備わっていないらしく、移植には少し苦労した。
    そこでVBには初めてLinkedListを使用したけど、存在すら知らなかった。
    インデックスは存在しないけど、順番は保持してくれて前後端の操作に優れているらしい。
    配列というものに動的なものを含めるかどうかでレギュレーションは変わるなぁ。
    オンライン実行環境: JavaScript, VB.net

    ループぶん回し HSP

    HSP

    kiyoshi.hsp
    #runtime "hsp3cl"
    #uselib "msvcrt.dll"
    randomize
    
    mes kiyoshi()
    #module Program
        #func printf "printf" str
        #defcfunc kiyoshi
            zundoko="ズン","ドコ"
            exit_kiyoshi="キ・ヨ・シ!"
            zdchk=0,0,0,0,1
            sdim stk,,length(zdchk)
            repeat
                zd=rnd(length(zundoko))
                stk0=stk(0)
                repeat length(stk)-1
                    stk(cnt)=stk(cnt+1)
                loop
                printf zundoko(zd)
                stk(length(stk)-1)=zundoko(zd)
                if stk0!=zundoko(zdchk(0)){
                    repeat length(stk)
                        if stk(cnt)!=zundoko(zdchk(cnt)){
                            break
                        }
                        if cnt=length(stk)-1{
                            return exit_kiyoshi
                        }
                    loop
                }
            loop
    #global
    

    特殊な操作を一切行わずに原始的な手段だけで解決。
    一番正解に近いのはコレだったりするのかもしれない。
    あと地味にHSPでは先駆者っぽい。

    with CommonLisp

    CommonLisp

    kiyoshi.lisp
    (defun kiyoshi()
        (setq *random-state* (make-random-state t))
        (let(
            (zundoko_list '("ズン" "ドコ"))
            (exit_kiyoshi "キ・ヨ・シ!")
            (zdchk '(0 0 0 0 1))
        )(let(
            (stc (mapcar #'(lambda(val)"") zdchk))
        )
            (defun fact(stc)
                (let(
                    (zd(random(length zundoko_list)))
                )(let(
                    (stczd (append (rest stc) `(,(elt zundoko_list zd))))
                )
                    (format t (elt zundoko_list zd))
                    (if (and
                        (string/= (first stc) (first zundoko_list))
                        (equal stczd (mapcar #'(lambda(val)(elt zundoko_list val)) zdchk))
                    )
                        exit_kiyoshi
                        (fact stczd)
                    )
                ))
            )
            (fact stc)
        ))
    )
    (format t (kiyoshi))
    

    Lispでもズンドコしてみた。
    再帰しまくって副作用をできるだけ出さないように書いてみた。
    慣れない書き方をしたので結構疲れた。
    Listの比較ができるequalは今回初めて知ったけど便利だ。
    CommonLisp

    おまけ:クラス/モジュール化 js/VB/HSP/CL

    ※最新版

    JavaScript

    nyaaan.js
    const zundoko=require("./zundoko");
    
    (function(){
        const zd=new zundoko();
        console.log(zd.kiyoshi());
        const nyaaan=new zundoko(["ぺぇこ","にゃん"],"ぺぇこぺぇこふぅーんふぅーんぺぇこふぅーんふぅー",[0,0,1,1,0,1,1]);
        console.log(nyaaan.kiyoshi());
    })();
    
    zundoko.js
    module.exports=function zundoko(_zundoko_list,_exit_kiyoshi,_zdchk){
        var zundoko_list;
        var exit_kiyoshi;
        var zdchk;
        this.zundoko=function(){
            if(zundoko.length==zundoko.arguments.length){
                zundoko_list=_zundoko_list;
                exit_kiyoshi=_exit_kiyoshi;
                zdchk=_zdchk;
            }
            else{
                zundoko_list=["ズン","ドコ"];
                exit_kiyoshi="キ・ヨ・シ!";
                zdchk=[0,0,0,0,1]
            }
        }
    
        this.kiyoshi=function(){
            var stk=new Array(zdchk.length);
            for(;;){
                var zd=Math.floor(Math.random()*zundoko_list.length);
                process.stdout.write(zundoko_list[zd]);
                stk.push(zundoko_list[zd])
                var stk0=stk.shift();
                if(stk0!=zundoko_list[zdchk[0]] && stk.join()==zdchk.map(val=>zundoko_list[val]).join()){
                    return exit_kiyoshi;
                }
            }
        }
        return this.zundoko();
    }
    

    VB.net

    nyaaan.vb
    Imports System
    Imports System.Console
    Imports zundoko
    
    Public Module Program
        Sub Main()
            Dim zd As New zundoko()
            WriteLine(zd.kiyoshi())
            Dim nyaaan As New zundoko({"ぺぇこ","にゃん"},"ぺぇこぺぇこふぅーんふぅーんぺぇこふぅーんふぅー",{0,0,1,1,0,1,1})
            WriteLine(nyaaan.kiyoshi())
        End Sub
    End Module
    
    zundoko.vb
    Imports System
    Imports System.Console
    Imports System.Collections.Generic
    
    Class zundoko
        Dim rand As New Random()
        Dim zundoko_list As String()
        Dim exit_kiyoshi As String
        Dim zdchk As Integer()
        Sub New()
            Me.zundoko_list={"ズン","ドコ"}.Clone
            Me.exit_kiyoshi="キ・ヨ・シ!"
            Me.zdchk={0,0,0,0,1}.Clone
        End Sub
    
        Sub New(zundoko_list,exit_kiyoshi,zdchk)
            Me.zundoko_list=zundoko_list.Clone
            Me.exit_kiyoshi=exit_kiyoshi
            Me.zdchk=zdchk.Clone
        End Sub
    
        Function kiyoshi() As String
            Dim rand As New Random()
            Dim stk As New LinkedList(Of String)(New String(zdchk.Length-1){})
            Do
                Dim zd As Long=rand.Next(zundoko_list.Length)
                Write(zundoko_list(zd))
                stk.AddLast(zundoko_list(zd))
                Dim stk0 As String=stk.First.Value
                stk.RemoveFirst()
                If stk0<>zundoko_list(zdchk(0)) And String.Join("",stk)=String.Join("",Array.ConvertAll(zdchk,Function(val) zundoko_list(val))) Then
                    Return exit_kiyoshi
                End If
            Loop
        End Function
    End Class
    

    HSP

    nyaaan.hsp
    #runtime "hsp3cl"
    #include "zundoko.as"
    
    newmod zd,zundoko
    mes kiyoshi(zd)
    
    newmod nyaaan,zundoko
    words="ぺぇこ","にゃん"
    fin="ぺぇこぺぇこふぅーんふぅーんぺぇこふぅーんふぅー"
    ptn=0,0,1,1,0,1,1
    set nyaaan,words,fin,ptn
    mes kiyoshi(nyaaan)
    
    zundoko.as
    #uselib "msvcrt.dll"
    randomize
    
    #module zundoko zundoko_list,exit_kiyoshi,zdchk
        #func printf "printf" str
    
        #modinit
            zundoko_list="ズン","ドコ"
            exit_kiyoshi="キ・ヨ・シ!"
            zdchk=0,0,0,0,1
        return
    
        #modfunc set array _zundoko_list,str _exit_kiyoshi,array _zdchk
            sdim zundoko_list,,length(_zundoko_list)
            repeat length(_zundoko_list)
                zundoko_list(cnt)=_zundoko_list(cnt)
            loop
            exit_kiyoshi=_exit_kiyoshi
            sdim zdchk,,length(_zdchk)
            repeat length(_zdchk)
                zdchk(cnt)=_zdchk(cnt)
            loop
        return
    
        #modcfunc kiyoshi
            sdim stk,,length(zdchk)
            repeat
                zd=rnd(length(zundoko_list))
                stk0=stk(0)
                repeat length(stk)-1
                    stk(cnt)=stk(cnt+1)
                loop
    
                printf zundoko_list(zd)
                stk(length(stk)-1)=zundoko_list(zd)
    
                if stk0!=zundoko_list(zdchk(0)){
                    repeat length(stk)
                        if stk(cnt)!=zundoko_list(zdchk(cnt)){
                            break
                        }
                        if cnt=length(stk)-1{
                            return exit_kiyoshi
                        }
                    loop
                }
            loop
    #global
    

    CommonLisp

    nyaaan.lisp
    (load "zundoko")
    (defparameter zd (make-instance 'zundoko))
    (format t "~a~%" (kiyoshi zd))
    
    (defparameter nyaaan (make-instance 'zundoko :words '("ぺぇこ" "にゃん") :fin "ぺぇこぺぇこふぅーんふぅーんぺぇこふぅーんふぅー" :ptn '(0 0 1 1 0 1 1)))
    (format t "~a~%" (kiyoshi nyaaan))
    
    zundoko.lisp
    (defun kiyoshi()
        (setq *random-state* (make-random-state t))
        (let(
            (zundoko_list '("ズン" "ドコ"))
            (exit_kiyoshi "キ・ヨ・シ!")
            (zdchk '(0 0 0 0 1))
        )(let(
            (stc (mapcar #'(lambda(val)"") zdchk))
        )
            (defun fact(stc)
                (let(
                    (zd(random(length zundoko_list)))
                )(let(
                    (stczd (append (rest stc) `(,(elt zundoko_list zd))))
                )
                    (format t (elt zundoko_list zd))
                    (if (and
                        (string/= (first stc) (first zundoko_list))
                        (equal stczd (mapcar #'(lambda(val)(elt zundoko_list val)) zdchk))
                    )
                        exit_kiyoshi
                        (fact stczd)
                    )
                ))
            )
            (fact stc)
        ))
    )
    (format t (kiyoshi))
    
    コンソール出力
    ズンドコドコズンズンドコドコドコズンドコドコズンズンズンドコズンズンズンドコドコドコドコドコドコドコズンズンズンズンズンドコズンドコドコズンドコドコドコズンドコドコドコドコズンズンズンドコズンズンズンドコズンズンドコズンドコズンドコズンドコドコズンドコズンドコズンズンズンドコドコドコドコドコドコドコドコドコズンズンズンズンドコキ・ヨ・シ!
    にゃんにゃんにゃんぺぇこにゃんにゃんにゃんにゃんにゃんにゃんぺぇこぺぇこぺぇこにゃんにゃんにゃんぺぇこにゃんにゃんぺぇこぺぇこにゃんにゃんにゃんぺぇこぺぇこにゃんにゃんぺぇこぺぇこにゃんにゃんぺぇこにゃんにゃんぺぇこぺぇこふぅーんふぅーんぺぇこふぅーんふぅー
    

    上記のプログラムをそのままクラス/モジュール化。
    使用方法は次の通り。

    js
    const zundoko=require("zundoko");
    var hoge=new zundoko([ズンドコパターン:配列], フィニッシュ台詞, [マッチパターン:int配列]);
    console.log(hoge.kiyoshi());
    
    VB
    Dim hoge As New zundoko([ズンドコパターン:配列], フィニッシュ台詞, [マッチパターン:int配列])
    Console.WriteLine(hoge.kiyoshi())
    
    HSP
    include "zundoko.as"
    newmod hoge,zundoko
    set hoge,[ズンドコパターン:配列], フィニッシュ台詞, [マッチパターン:int配列]
    //setしなければ通常のズンドコキヨシ
    mes kiyoshi(hoge)
    
    CL
    (load "zundoko")
    (defparameter hoge (make-instance 'zundoko :words [ズンドコパターン:リスト] :fin フィニッシュ台詞 :ptn [マッチパターン:intリスト]))
    (format t "~a~%" (kiyoshi hoge))
    

    クラス/モジュールファイルを同じフォルダにおいてこのようにすれば、好きなワードやパターンでズンドコ可能。
    オンライン実行環境: JavaScript, VB.net, CommonLisp

    Excel

    excelkiyoshi.png
    kitoshigs.png

    EXCEL
    =IFERROR(
        IF(AND(
            "ズン"=INDIRECT(ADDRESS(ROW()-5,COLUMN())),
            "ズン"=INDIRECT(ADDRESS(ROW()-4,COLUMN())),
            "ズン"=INDIRECT(ADDRESS(ROW()-3,COLUMN())),
            "ズン"=INDIRECT(ADDRESS(ROW()-2,COLUMN())),
            "ドコ"=INDIRECT(ADDRESS(ROW()-1,COLUMN()))
        ),
            IF(
                ISERROR(IF("ズン"<>INDIRECT(ADDRESS(ROW()-6,COLUMN())),
                    NA(),
                    0
                )),
                "キ・ヨ・シ!",
                NA()
            ),
            IF(NOT(ISERROR(MATCH(
                "キ・ヨ・シ!",
                INDIRECT(
                    ADDRESS(1,COLUMN())&":"&
                    ADDRESS(ROW()-1,COLUMN())
                ),
                0
            ))),
                "",
                NA()
            )
        ),
        IF(RANDBETWEEN(0,1)=0,
            "ズン",
            "ドコ"
        )
    )
    

    一セルに情熱を。
    2番煎じですけど作成。
    好きなセルに上記を貼り付けて上下に適当にズザーすれば使用できます。
    GoogleSpreadでも動いたのでリンク置いときます。

    実行環境

    JavaScript: node v4.3.2
    VB.net: vbc 14.0.1055
    HSP 3.32
    CommonLisp: CLISP 2.49, SBCL 1.2.7
    MS Excel 2007
    及び、Rextester