クリス・パインの「ろうおばあちゃん」


22

私はRubyLearningのメンターであり、私たちが生徒に提供するエクササイズの1つは、クリス・パインの本「Learn to Program」の「ろうおばあちゃん」エクササイズです。説明は次のとおりです。

ろうおばあちゃんプログラムを書く。おばあちゃんに何を言っても(入力したものは何でも)、彼女は叫ぶ(すべて大文字で入力する)場合を除き、「ハァッ!声を上げて、息子よ!」あなたが叫ぶと、彼女はあなたの声を聞くことができ(少なくとも彼女はそう思う)、「いいえ、1938年以来じゃない!」と叫ぶ。

あなたのプログラムを本当に信じられるものにするために、おばあちゃんは毎回異なる年を叫んでください。多分、1930年から1950年の間の任意の年。 「BYE」と叫ぶ。

いくつかのコースを繰り返した後、私はこれをどれだけ小さくできるかを試してみましたが、今では112文字になりました。

puts (s||='').upcase==s ? "NO, NOT SINCE #{1930+rand(21)}!":"HUH?! SPEAK UP, SONNY!" until(s=gets.chomp)=="BYE"

ここでRubyはすでに非常にうまく機能していると思うので、あなたが選択した言語でこれを達成できる文字数が少ないことに興味があります。

編集:以下に投稿されたPerlソリューションは、

ruby -nle 'puts($_=="BYE"?exit: $_.upcase!? "HUH?! SEPAK UP, SONNY!":"NO, NOT SINCE #{1930+rand(21)}!")'

式は92文字nlオプションとオプションはさらに2文字です。


ゴルフの文脈では、これには追加の仕様が必要です。BYEを超えて余分な出力がある場合はどうなりますか?
JB

「BYE」のみがプログラムを正確に終了します。
マイケルコール

回答:


13

Perl、85 91

で実行perl -nE '<code goes there>'nプログラムサイズでカウント):

$==1930+rand 21;say/^BYE$/?last:uc eq$_?"
NO, NOT SINCE $=!":"HUH?! SPEAK UP, SONNY!"

その末尾の感嘆符は非常に高価です...

IKが提案する編集:

  • 文字列一致の代わりに正規表現を使用すると、-lグローバルオプションと2つのプログラム文字が不要になります。
  • 実際の変数を使用して値を保存し、後で補間に使用します(Genius!そのために変数を使用することを考えた人は誰ですか?):0
  • その変数を作成して$=、整数に制限します:-4。

(それでもまだ足りず、眠いのでその理由がわかりません。まあ、少なくとも最終的なカウントは正しいです)


悪用$=と「BYE」のための正規表現を使用すると、84 + 1に、このダウンを取得しますperl -nE '$==1930+rand 21;say/^BYE$/?last:uc eq$_?"NO, NOT SINCE $=!":"HUH?! SPEAK UP, SONNY!"'
イルマリKaronen

@IlmariKaronen Integrated、ありがとう!
JB

6

Python 120キャラクター

r=raw_input
s=r()
while'BYE'!=s:
 print["HUH?! SPEAK UP, SONNY!","NO, NOT SINCE %d!"%(1930+id(s)%21)][s.isupper()];s=r()

改善するヒントはありますか?


if文を囲む括弧は必要ありません。また、pythonには再帰の上限があると確信しています-しかし、それはあなたのおばあちゃんが眠りに落ちることをシミュレートするだけです。
-Phoshi

ああ!ブラケットを取り外すのを忘れました。ありがとう:)
fR0DDY

あなたは、最初の行を削除して二を交換する場合は、一部の文字を保存することができますs='':あなたのwhileループでは、あなたの文、並べ替え、および1つの行に全体whileループを入れgist.github.com/3787809あなたが本当に決定した場合は、可能性がありpython 3を使用して2文字を保存します(raw_input()-> input()、print-> print())
マット

4

PowerShellの131文字:

for(){$j=read-host;if($j-ceq"BYE"){break}if($j-ceq$j.ToUpper()){"No, not since 19$(10..90|random)!"}else{"Huh?! Speak up, sonny!"}}

空白あり:

for(){
  $j = read-host;
  if ( $j -ceq "BYE" ) { break }
  if ( $j -ceq $j.ToUpper() ) { "No, not since 19$(10..90|random)!" }
  else { "Huh?! Speak up, sonny!" }
}

ジョーイの提案から18文字を絞った。

ところで、「Learn to Program」は、私が今まで読んだ最初のプログラミング本でした。


こちらをご覧ください:codegolf.stackexchange.com/questions/191/…–
Joey

これをif...条件付きチェックに最初のものを詰め込むことで、これを120まで下げることができますfor()for(;($j=read-host)-cne"BYE"){if($j-ceq$j.ToUpper()){...また、仕様には1930-1950と書かれています。
SpellingD

3

C#-234文字

using System;class P{static void Main(){for(;;){var s=Console.ReadLine();if(s!=s.ToUpper()){Console.WriteLine("Huh?! Speak up, sonny!");continue;}if(s=="BYE")break;Console.WriteLine("No, not since 19{0}!",new Random().Next(30,51));}}}

より読みやすい:

using System;
class P
{
    static void Main()
    {
        for(;;)
        {
            var s=Console.ReadLine();
            if(s!=s.ToUpper())
            {
                Console.WriteLine("Huh?! Speak up, sonny!");
                continue;
            }
            if(s=="BYE")
                break;
            Console.WriteLine("No, not since 19{0}!",new Random().Next(30,51));
        }
    }
}

ああ、私の簡単なものをいくつか見逃し、いくつかの愚かな間違いを犯しました。素敵な+1
カイル・ロゼンド

3

Befunge-27x6 = 162文字

> ~:0`  #v _            vv<
         >:"a"`!#v  _:"z"`|
^                <       <
v"Huh?! Speak up, sonny!"0<
v"No, not since 1938!"0 <
>:# #, _@

編集:「BYE」の部分を完全に逃しました。新しいバージョンは近日公開予定。

編集2:実際、それは私の貧弱なBefungeスキルにとっては少し複雑すぎます。後でもう一度試すかもしれませんが、現時点でそれを実装する簡単な方法は考えられません。


3

C#-194文字

using System;class P{static void Main(){var s=Console.ReadLine();if(s!="BYE"){Console.Write((s==s.ToUpper()?"No, not since 19"+new Random().Next(30, 51):"Huh?! Speak up, sonny")+"!");Main();}}}

空白あり:

using System;
class P
{
    static void Main()
    {
        var s = Console.ReadLine();
        if (s != "BYE")
        {
            Console.Write((s == s.ToUpper() ? "No, not since 19" + new Random().Next(30, 51) : "Huh?! Speak up, sonny") + "!");
            Main();
        }
    }
}

NelliusとfR0DDYからインスピレーションを得て。

改善できるかどうか教えてください。


短いですが、FWIW、これはリークしていると思います(再帰的に呼び出しますMain())。また、?:式のかっこ!で両方を取得する必要があると思います。私はこれとEOLで答えを追加しました(しかし、まだ漏れています)。
-bw

かっこを追加し、コメントを削除したことがわかります。よくやった。今、括弧付きとなしの私の答えにスクリーンショットを追加するための編集は無意味です。(しかし、まだ漏れやすい):-)
bw

@billはい、最初はテストを台無しにしました。漏れのないバージョンは199文字で、長すぎます:)
リチャード

ハ。私はMain();解決策が好きです...正気な人はこのプログラムを問題になるほど長く使用しません。
-bw

PhoshiがfR0DDYへのコメントで述べたように。おばあちゃんが寝入ったときにプログラムがクラッシュします。
リチャード

3

D:246文字

import std.random,std.stdio,std.string;void main(){auto r=rndGen();for(;;){auto t=strip(readln());if(t=="BYE")break;if(t.toupper()==t)writefln("No, not since %s!",{r.popFront();return r.front%20+1930;}());else writeln("Huh?! Speak up, sonny!");}}

より読みやすく:

import std.random, std.stdio, std.string;

void main()
{
    auto r = rndGen();

    for(;;)
    {
        auto t = strip(readln());

        if(t == "BYE")
            break;

        if(t.toupper() == t)
            writefln("No, not since %s!", {r.popFront(); return r.front % 20 + 1930;}());
        else
            writeln("Huh?! Speak up, sonny!");
    }
}

3

javascript、142文字、そのうち29個はランダムな年を実行します

n='a'; while((/[a-z]/.test(n)?r="HUH?! SPEAK UP, SONNY!":n=="BYE"?r='':r="NO, NOT SINCE "+Math.floor(Math.random()*21+1930))!=''){n=prompt(r)}

3

Awk:97文字

$0=="BYE"{exit}$0=toupper($0)==$0?"NO, NOT SINCE "int(rand()*21+1930)"!":"HUH?! SPEAK UP, SONNY!"

3

Windows PowerShell、121 117

タスクの性質上、これはTy Auvilのソリューションとほとんど同じに見えますが、独立して記述されています。

for(;($j=read-host)-cne'BYE'){if($j-cmatch'[a-z]'){'Huh?! Speak up, sonny!'}else{"No, not since 19$(30..50|random)"}}

SpellingDの提案に感謝します。


私はあなたの正規表現のマッチングが好きですが、switchステートメントはかなりかさばります。私がTyに与えた提案に加えて、次のifような正規表現を使用して、文字数を117に減らすことができますfor(;($j=read-host)-cne'BYE'){if($j-cmatch'[a-z]'){'Huh?! Speak up, sonny!'}else{"No, not since 19$(30..50|random)"}}
SpellingD

2

ハスケル(189)

import Random
import Char
main=getLine>>=g
g"BYE"=return""
g s|s/=map toUpper s=putStrLn"HUH?! SPEAK UP SONNY!">>main|4>2=randomRIO(30,50::Int)>>=putStrLn.("NO, NOT SINCE 19"++).show>>main

奇妙なことに、「深刻な」プログラムを作成する場合、Haskellコードは通常、同等のCコードよりもはるかに短いです。


Charを使用any(`elem`['a'..'z'])sして小文字をテストすることにより、インポートを回避できます。
ハマー

2

APL(76)

 {'BYE'≢A←⍞:∇⎕←{∧/⍵∊⎕A:'No, not since ',⍕1938+?20⋄'Huh?! Speak up sonny!'}A}⍬

1

C#-345文字

using System;class Program{static void Main(){for(;;){if(!t(Console.ReadLine()))break;}}static bool t(string s){bool b=false;if(s=="BYE")return b;int i=0;for(;i<s.Length;i++){b=(s[i]>65&&s[i]<90)?true:false;if(!b)break;}if(b) p("NO, NOT SINCE 1938!");else p("HUH?! SPEAK UP, SONNY!");return true;}static void p(string s){Console.WriteLine(s);}}

くそったれ言語... :-)


1
あなただけのクラスを呼び出すことができますP。そして、これは大文字を正しく検出しません。私はそれを叫ぶことができ、それでも私には聞こえません。mainメソッドをに短縮できwhile(t(Console.ReadLine()));ます。あなたは使用することができますusing C=System.Console;へのアクセスを短縮するために開始時ReadLine()WriteLine()するC.ReadLine()C.WriteLine()
ジョーイ

@Joey-ヒントをありがとう!
カイル・ロゼンド

1

C#-196文字(ただし漏れやすい)

using System;class P{static void Main(){var s=Console.ReadLine();if(s!="BYE"){Console.Write((s==s.ToUpper()?"No, not since 19"+new Random().Next(30, 51):"Huh?! Speak up, sonny")+"!\n");Main();}}}

それは@Richardの(漏れやすい)答えであり、2つの括弧(以下を参照)と両方の場合にEOLを取得するためにそこに\ nが追加されています。それ以外の場合は、" + "無駄なスペースです。

フォーマット済み

using System;
class P
{
    static void Main() { 
        var s = Console.ReadLine(); 
        if (s != "BYE") { 
            Console.Write((
                s == s.ToUpper() ? 
                "No, not since 19" + new Random().Next(30, 51) : 
                "Huh?! Speak up, sonny"
                ) + "!\n");
            Main(); 
        } 
    }
}

更新:必要なかっこについての私のコメントを明確にするために、かっこなしで(つまり@Richardの元のソリューションで)得られるものを以下に示します。

括弧なし

そして括弧で:

括弧付き

これらのどちらも私の追加を使用しません\n


ここでは195です。最後に不要な改行を数えましたか?
ジョーイ

1

バッシュ:136 128文字

while read s
do
[[ $s = BYE ]]&&break
[[ ${s^^} = $s ]]&&echo NO, NOT SINCE $[RANDOM%21+1930]!||echo HUH?! SPEAK UP, SONNY!
done

代替選択肢:132 123文字

f(){
read s
[[ $s = BYE ]]||{
[[ ${s^^} = $s ]]&&echo NO, NOT SINCE $[RANDOM%21+1930]!||echo HUH?! SPEAK UP, SONNY!
f
}
}
f

聴覚障害者とは無限に会話できますが、この後のコードとの会話は呼び出しスタックによって制限されます。(私のテストでは、4989の呼び出し後に終了します。)


1

ジャバスクリプト- 133 131 130 128 127 121文字

www0z0ksソリューションのゴルフバージョン

g='';while((i=prompt(g))!='BYE'){/[a-z]/.test(i)?g='Huh?! Speak up, sonny!':g='No, not since '+Math.floor(Math.random()*21+1930)+'!'}

g='';while((i=prompt(g))!='BYE'){g=/[a-z]/.test(i)?'Huh?! Speak up, sonny!':'No, not since '+Math.floor(Math.random()*21+1930)+'!'}

g='';while((i=prompt(g))!='BYE'){g=/[a-z]/.test(i)?'Huh?! Speak up, sonny!':'No, not since '+Math.ceil(Math.random()*21+1929)+'!'}

for(g='';(i=prompt(g))!='BYE';g=/[a-z]/.test(i)?'Huh?! Speak up, sonny!':'No, not since '+Math.ceil(Math.random()*21+1929)+'!');

for(g='';(i=prompt(g))!='BYE';g=/[a-z]/.test(i)?'Huh?! Speak up, sonny!':'No, not since '+parseInt(Math.random()*21+1930)+'!');

for(g='';(i=prompt(g))!='BYE';g=/[a-z]/.test(i)?'Huh?! Speak up, sonny!':'No, not since '+(Math.random()*21+1930|0)+'!');

編集:この素晴らしいヒントでさらに6文字を保存しました


三項演算子をとして記述しg=/[a-z]/.test(i)?'Huh?!...':'No...'、2文字を節約します。
マナトワーク

編集、ポインタをありがとう。
codeporn

1
私が見つけたもう1つの文字:Math.ceil()は未満Math.floor()です。間隔を変更しないように基準年を変更しますMath.ceil(Math.random()*21+1929)
マナトワーク

+1 whileをforループに変更して、さらに2文字を保存しました。
codeporn

0

Clojure- 160 154キャラクター

(#(if(= % "BYE")%(do(if(=(.toUpperCase %)%)(prn(str"No, not since "(+ 1930(rand-int 9))"!"))(prn"Huh?! Speak up, sonny!"))(recur(read-line))))(read-line))

それをもう少しゴルフに取り組んでいます。提案を歓迎します。

REPLを実行する


0

Q、115

{while[1;v:read0 0;$[v~"BYE";'`;v~upper v;-1"No, not since ",/:(($)1?1930+(!)20),'"!";-1"Huh?! Speak up, sonny!"]]}

使用法

q){while[1;v:read0 0;$[v~"BYE";'`;v~upper v;-1"No, not since ",/:(($)1?1930+(!)20),'"!";-1"Huh?! Speak up, sonny!"]]}`
Hi
Huh?! Speak up, sonny!
Hello
Huh?! Speak up, sonny!
HELLO!
No, not since 1938!
Goodbye Grandma
Huh?! Speak up, sonny!
BYE
'
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.