ASCIIアートで長い分割を視覚化する


16

ASCIIアートで長い除算を視覚化するプログラムを作成します。入力は、選択した入力形式を使用して、分子と分母の2つの整数で構成されます。

例:

1234÷56:

     22
   ----
56|1234
   112
   ---
    114
    112
    ---
      2

1002012÷12:

     83501
   -------
12|1002012
    96
   ---
     42
     36
     --
      60
      60
      --
        12
        12
        --

0÷35

   0
   -
35|0

ルール:

  • プログラミング言語の除算演算子の使用許可されています。
  • 大きな整数のサポートの使用も許可されています。
  • 一貫性のために:
    • 商がゼロの場合、ダイビングボードの最後にゼロを1つ出力します。
    • 余りがゼロの場合、印刷しないでください。
    • 数字に先行ゼロを印刷しないでください。
  • 末尾の余分な改行と右側の末尾のスペースは許可されます。
  • 最小の文字数のソリューションが勝ちです。

制限:

  • 0 <=分子<= 10 72 - 1
  • 1 <=分母<= 9999999

これは、出力が80列を超えないことを意味します。

テストスイートとサンプル実装:

long-division.cgist)を使用して、プログラムをテストできます。実際には、Cプログラムが内部にあるbashスクリプトです。テストスイートでプログラムを呼び出すためにそれを微調整します。参照実装を確認するには、下部のCコードをご覧ください。サンプルプログラムまたはテストスイートに問題がある場合はお知らせください。

$ ./long-division.c 10 7
   1
  --
7|10
   7
  --
   3
$ ./long-division.c
PASS 1234 ÷ 56
PASS 1002012 ÷ 12
PASS 1 ÷ 1
--- snip ---

Score: 35 / 35
All tests passed!

編集:リクエストに応じて、テストスイートの入力予想される出力をテキストファイルに入れます(gist)。サンプル使用法(bash):

cat input | while read nd; do
    ./program $nd |
        sed 's/\s*$//' | sed -e :a -e '/^\n*$/{$d;N;};/\n$/ba'
done > output

diff -u expected output

奇妙なsedコマンドは、プログラム出力から末尾の改行とスペースを除外します。


リファレンス実装で、つまり123000123000123÷123の場合に小さな欠陥を発見しました。減算ラインは空白にまたがっていましたが、被減数の目に見える桁の長さにのみまたがっていなければなりません。現在修正されています。
ジョーイアダムス

2
私は、出力が英語圏のゴルフの観客に偏って少しだと思う:en.wikipedia.org/wiki/...
hallvabo

すべてのテストの期待される出力を示すファイルを作成し、それにリンクできますか?
mellamokb

@mellamokb:追加、ありがとう!
ジョーイアダムス

受け入れはどうですか?質問は古い十分...である
オレグPrypin

回答:


3

Python 3、284 257文字

div.py

n,t=input().split()
d=int(t)
l=lambda x:len(str(x))
s=l(n)
def p(x):print(' '*(l(d)+s-l(x)+1)+str(x))
p(int(n)//d)
p('-'*s)
p(t+'|'+n)
s=z=f=0
while t:
 try:
  while z<d:z=z*10+int(n[s]);s+=1
 except:t=0
 if z*f:p(z)
 if t:f=1;t=z//d*d;p(t);p('-'*l(z));z-=t

使用法:python3 div.py
入力:キーボードから

test.py

import sys
sys.stdin=open('input'); sys.stdout=open('output','w')
for line in open('input'): exec(open('div.py').read())

予想される出力と一致

バージョン:
 1. 284
 2. 257s,z,f=0,0,0s=z=f=0; z and fz*f; より良いループ; いくつかの改行を削除しました。


2
あなたはpython3と入力のためにideoneを試すことができます-ideone.com/clone/ZZyzu
YOU

3

Haskell、320文字

l=length
(®)=replicate
p!v=p&show v
p&s=(p-l s)®' '++s
0§_=[];_§l=l
d[m,n]=l c!(read m`div`e):l c&(l m®'-'):c:drop 1(g 0(map(toInteger.fromEnum)m)$1+l n)where
 e=read n;c=n++'|':m
 g r(d:z)p=i§[o!k,o!(i*e),o&(l(show k)®'-')]++g j z o where k=r*10+d-48;(i,j)=k`divMod`e;o=1+p
 g r[]p=r§[p!r]
main=interact$unlines.d.words

すべてのテストに合格します。これはかなりのゴルフですが、まだここでやるべきことがまだあると思います...


  • 編集:(344 - > 339)は、遅延read呼び出し、呼び出しに必要性を低減show略していることは十分、showなどがsそれだけの価値はありません。
  • 編集:(339-> 320)文字列フィールドのフォーマット関数を書き直しました

きちんとした!344文字のHaskellソリューションを作成しましたが、投稿しませんでした。また、演算子にUnicodeシンボルを使用できるとは知りませんでした(なし-XUnicodeSyntax)。
ジョーイアダムス

3

JavaScript(400 394 418

function d(n,d){t=parseInt;p=function(v){return(s+v).substring(v.length)};a=function(v,c){return v.replace(/\d/g,c)};w='\n';q=b=o=c=e='';s=a(d,' ')+' ';f=true;i=-1;z='0';while(++i<n.length){s+=' ';if(t(c+=n[i])>=t(d)){q+=r=Math.floor(t(c)/t(d));o+=(!f?p(c)+w:e)+p(''+r*t(d))+w+p(a(c,'-'))+w;c=t(c)%t(d);f=false}else if(!f){q+=z;}c=(c==0)?e:e+c}return p(!q?z:q)+w+p(a(n,'-'))+w+d+'|'+n+w+o+(q?p(c):e)}

注:に置き換えc=(c==0)?ていくつかの文字を削り取るように見えるのは魅力的c=!c?ですが、浮動小数点関連のバグが発生するため使用できません。

http://jsfiddle.net/nLzYW/9/

サンプル実行:

document.writeln("<pre>");
document.writeln(d("1234","56"));
document.writeln();
document.writeln(d("1002012","12"));
document.writeln();
document.writeln(d("0","35"));
document.writeln();
document.writeln(d("123000123000123","123"));
document.writeln("</pre>");

編集1:マイナーバグ修正、多数のコード最適化。

編集2:1/7が余分な出力を生成するバグを修正。


テストスクリプトは1つの問題を明らかにしました。 d(1,7)(および同様のテスト)何も出力しないで、分母を繰り返します。この数字は商の数字に分母を掛けたものでなければならないため、これは間違っています。
ジョーイアダムス

すべてのテストに合格しました。
ジョーイアダムス

1

Javascript:(372)

function g(a){for(var c="",e=0;e<a;e++)c=" "+c;return c}function i(a,c){for(var e=a+"/"+c+"\\",j=(""+c).split(""),k="",d=0,b=0;b<j.length;b++){d*=10;d+=parseInt(j[b],10);var f=d>9?b-1:b,h=0;h=Math.floor(d/a);d%=a;f=g(f+a.toString().split("").length);f+=h*a+"\n"+g(b+a.toString().split("").length)+"--\n"+g(b+a.toString().split("").length)+d+"\n";k+=f;e+=h}return e+"\n"+k}

i(divider、number)を使用して呼び出します。Codegolfed JS:http: //jsfiddle.net/puckipedia/EP464/ Ungolfed(オランダ語)JS:http ://jsfiddle.net/puckipedia/M82VM/

長い除算を返します(私が学んだようにオランダ語の形式で):

5/25\05
 0
 --
 2
 25
  --
  0

テストケース:

document.write("<pre>"+i(5,25)+"</pre>");
document.write("<pre>"+i(7,65669726752476)+"</pre>");

ねえ、これは必要なものと同じではありません!
オレPrypin

@BlaXpirit私は知っている、私はそれをそのように学んだ。
puckipedia

面白い。@BlaXpiritが言うように、仕様には従いません。仕様は、コードゴルフコードの効率を判断するための公正な比較基準となることを目的としているため、出力形式に同意しない場合でも仕様を任意に変更することはできません:)
mellamokb
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.