黄色の木で分岐した2つの道路(パート2)


25

これはシリーズの2番目で、3番目は黄色の木で分岐した2つの道路です(パート3)

これは、私の以前の課題であった黄色の木に分かれ2つの道路(パート1)に基づいています。かなり好評でしたが、かなり些細なものでした(Javaの52バイトの回答です!)

インスピレーション

この課題は、ロバートフロストの有名な詩「The Road Not Taken」に触発されたものです。

2本の道が黄色い木に分かれていて、
残念ながら私は両方を旅行することはできず
、一人の旅行者であり、長く立ち、そしてできる限り
1本を見下ろした

... 2段落トリミング...

私はこれを
どこか年齢と年齢のためにため息をつくことで伝えます
。2本の道が森の中に分かれていて、
私は旅の少ない方を連れて行きました

最後から2番目の行に注目してくださいI took the one less traveled by,。あなたの目標は、文字列入力で最も移動の少ない道路を見つけることです。互いに異なる2つの値のいずれかを出力する必要があります。この値は、どの道を曲がって道路の移動量を減らすかを示します。道路の分岐点(六角形の軌跡が数字に変わる)が交差点にあります。そこから、数字で構成される2つのパスがあります。数字の合計が最小のパスは、撮影されていない道路になります。通行されていない道路のパスは大きいが、パスの合計は小さいことに注意してください。以下は、使用されていないパスに対して「左」または「右」を出力するプログラムの例/テストケースです。

 1     2
  1   2
   1 2
    #
    #
    #
left (3 < 6)


 1     2
  2   2
   1 1
    #
    #
    #
left (4 < 5)


 12    2
  11  2
   1 1
    #
    #
    #
right (6 > 5)


 99   989
  99  89
  99 99
  99 99
    #
    #
    #
   # 
left (72 < 79)


1111 1110
 001 111
  11 11
  11 11
    #
   ##
  ##
 ##  
left (9 < 10) (Note: 1111 is interpreted as 1+1+1+1=4, not 1111=1111)


1       1
 0     1
  1   1
  1   1
  1   1
  1   1
   1 1 
    #
    #
    #
     #
      #
left (6 < 7)


1   1 
 0   1  
  1   1
  1   1
  1   1
  1   1
   1 1 
    #
    #
    #
     #
      #
left (6 < 7)

想定して覚えておくべきこと

  • 常に2つのパスがあります。これ以上でもそれ以下でもありません。
  • STDINから一度に1行、LF文字を含む文字列、またはリテラルのバックスラッシュとnを含む文字列を入力できます。他の方法で入力が必要な場合は、コメントで承認を求めてください。
  • 無効な入力や関連付けられたパスについて心配する必要はありません。これらがプログラム/機能に入力されることはありません。
  • 入力は、言語の文字列制限よりも小さい任意の長さの幅または高さにすることができます。
  • #同じ行にa と番号はありません。
  • パス内のすべての数字は、0〜9の正の整数です。
  • 入力または出力の末尾に改行を使用できます。
  • 例については、以下のJS ES6の回答を参照しください。
  • 2つのパスの間には常に少なくとも1つのスペースがあります。
  • 2つのパスの高さは各マップで常に同じですが、他のマップでは異なる場合があります。
  • 特定のテストケースについて混乱している場合は、教えてください。
  • 1111は、1111 = 1111ではなく、1 + 1 + 1 + 1 = 4として解釈されます。マップは一連の1桁の数字であり、任意の長さの数字ではありません。
  • これはなので、バイト単位の最短回答が勝ちです!
  • 禁止されている標準的な抜け穴

このチャレンジについて質問がある場合は、コメントでお尋ねください。


ねえ、あなたは$("div > h1").map(function(){return $(this).text()}).get().join("\n");あなたのコンソールに貼り付けることですべての答えとそのバイト数を見ることができます!
Programmer5000

1
空白を削除して取り消し線付きの回答を無視した代替バージョンを次に示しますlet answers = $('div > h1').map(function(){return $(this).clone().children(':not(a)').remove().end().text().replace(/\s+/g,' ').trim()}).get();answers.splice(0, 1);answers.join('\n');
デビッドアーチボルド

2
#は六角形ではありません
...-user253751

1
しかし、それはかなり些細なことでした(52バイトでJavaが答えます!)43バイト。;)
ケビンクルーイッセン

再び投票する?一体何が悪いの?
マシュー

回答:


2

05AB1E21 15バイト

左に0、右に1を出力します。

|vy#õK€SO})øO`›

オンラインでお試しください!

説明

|v                # for each line in input
  y#              # split on spaces
    õK            # remove empty strings
      €S          # split each string into a list of chars
        O         # sum each sublist
         }        # end loop
          )ø      # wrap stack in a list and zip
            O     # sum each sublist (side of the tree)
             `›   # compare left to right

11

網膜、28バイト

\d
$*
%r`1\G
-
Os`.
+`-1

1+

オンラインでお試しください!

0左と1右に印刷します。どの行にも末尾のスペースがないと仮定します。

説明

\d
$*

各桁Nを一連の1に変換しNます。

%r`1\G
-

各行に1つ(%)、\G最後から連続する()に一致()し、rそれぞれを置き換えます-(つまり、右の分岐を-sに変えます)。

Os`.

すべての文字がすべての文字の-直前にくるように、すべての文字を並べ替えます1

+`-1

-とのペアを繰り返しキャンセルし1ます。

1+

少なくとも1つを一致させてください1(一致する場合は、左のパスにより多くの重みがあります)。



7

チップ、216バイト

 EZ,Z~.
E~]x-.|
F].>vm'
Ax]}#----------------.
Bx]}#---------------.|z.
Cx]}#------------.,Z|##' E
Dx]}#---------.,Z|`@@('A~^~t
 E.>#------.,Z|`@@-('
A~S`#v--.,Z|`@@-('
*f,--<,Z|`@@-('
e |,Z|`@@-('
,Z|`@@-('
>@@-('
a

オンラインでお試しください!

パート1の答えより少し大きい...

概要

チップは、実際の回路に触発された2D言語であり、バイトストリームの各バイトのコンポーネントビットを処理します。

このソリューションは、表示される数字の合計を保持し、空白のストレッチに遭遇するたびに入力の符号を反転し、最初ので終了します#。したがって、入力用

 11   12
  2   2
   1 1
    #
    #
    #

取得し1 + 1 - 1 - 2 + 2 - 2 + 1 - 1 = -1ます。結果の符号は出力として与えられ、負の数は結果を生成し、1正の数は0です。

したがって、の出力は1、左のパスの方が少ないことを意味し、0右を意味します。

説明

高レベルでは、これがどのように機能するかです:

@要素との主な対角線はアキュムレータであり、出力はa下部で決定されます。(8ペア@は8ビットを意味しますが、最上位ビットは符号であるため、このソリューションは+127または-128の最大差を処理できます。途中でオーバーフローしても問題ありません。終了する前に戻ってくる限り)。

Ax]}#--...のように始まる4行は入力を読み取り、数字の場合は(必要に応じて)否定し、値を加算器に渡します。

最初の3行は、数字または空白のシーケンスのどちらを見るかを決定し、数字を無効にする必要があるかどうかを追跡します。

入力の下に挟まれた残りの要素と右端の要素は終了条件を処理し、出力をASCIIにマッピングします(したがって、文字'0'または'1'0x0または0x1。含まれています。)


2
私はコードが2つの分岐する道路のように見えることが好きです。
ライコニ

@Laikoni私も気づかなかった、それはちょっとクールです:)
Phlarx

4

JavaScript(ES6)、55バイト

x=>x.replace(/\d(?=.*( )|)/g,(d,s)=>t-=s?d:-d,t=0)&&t<0

末尾の各ライン上のスペース、及び出力が存在しない前提trueのためrightfalseのためにleft。トリックは、入力の各桁を一致させることです。同じ行でその後にスペースがある場合は、合計からそれを減算します。それ以外の場合は、合計に追加します。最終合計が0未満の場合、右側の道路は通行距離が少ない道路であり、その逆も同様です。

やってみて:

f=x=>x.replace(/\d(?=.*( )|)/g,(d,s)=>t-=s?d:-d,t=0)&&t<0
<textarea placeholder = "paste in a map here..." oninput = "document.querySelector('div').innerText = f(this.value)"></textarea>
<div></div>


x=式は許可されず、変数として保存された関数とプログラム全体のみが許可されるため、先頭にaを付ける必要があります。
Programmer5000

@ programmer5000なぜですか?デフォルトを上書きするのは少し奇妙に思えますが、これが問題のケースであることを示すようには見えません。
小麦ウィザード

1
@ programmer5000実際には、名前のない関数はデフォルトで許可されています。(スニペットのおかげで、ところで)
ETHproductions



2

網膜、180バイト

バイトカウントはISO 8859-1エンコードを前提としています。

^(?=( *(0|(1|(?<3>2|(?<3>3|(?<3>4|(?<3>5|(?<3>6|(?<3>7|(?<3>8|(?<3>9))))))))))+.+¶)+)(.+ (0|(?<-3>1|(?<-3>2|(?<-3>3|(?<-3>4|(?<-3>5|(?<-3>6|(?<-3>7|(?<-3>8|(?<-3>9))))))))))+¶)+ *#

オンラインでお試しください!

私はまた、正規表現のみのソリューションを(上記用いた以外は、正しい道をとるべき唯一の入力に一致するプレーンな.NETの正規表現で試してみようと思いましたの省略形として\n)。

面倒な繰り返しですが、可能性のある各桁を個別に処理する必要がある場合に発生します。

ソリューションは、バランスグループのかなり単純なアプリケーションです。まず、各桁のNスタック3にキャプチャをプッシュすることにより、左ブランチの桁を合計しますN。次に、右側のブランチの各桁の#スタック3 N時間からポップしながら、に到達しようとしますN。これは、左のブランチの数字の合計が右のブランチの数字の合計よりも大きい場合にのみ可能です(空のスタックからポップできないため)。


私は.NET正規表現に精通していませんが、文字セットを実行できません:[0-9]すべての数字を一致させるか、\d
Programmer5000

@ programmer5000もちろん、しかしそれらを区別することはできず、それらを合計するためにプッシュする必要のあるキャプチャの数を決定することはできません。
マーティンエンダー

2

JavaScript(ES6)、106 104バイト

s=b=>(b=b.split`\n`,c=0,d=0,b.forEach(a=>{a=a.match(/\d+/g)||[],c+=+(a[0]?a[0]:0),d+=+(a[1]?a[1]:0)}),c<d)

s=b=>(b=b.split("\n"),c=0,d=0,b.forEach(a=>{a=a.match(/\d+/g)||[],c+=+(a[0]?a[0]:0),d+=+(a[1]?a[1]:0)}),c<d)

sは、true撮影されていない道路が左側にある場合に返される関数です。ゴルフをしていない:

var proc = function(str){
    str = str.split("\n");
    var left = 0;
    var right = 0;
    str.forEach(item=>{
        var match = item.match(/\d+/g) || [];
        console.log(match);
        left += +(match[0] ? match[0] : 0);
        right += +(match[1] ? match[1] : 0);
    });
    return left < right;
};

s=b=>(b=b.split`\n`,c=0,d=0,b.forEach(a=>{a=a.match(/\d+/g)||[],c+=+(a[0]?a[0]:0),d+=+(a[1]?a[1]:0)}),c<d)
<textarea placeholder = "paste in a map here..." oninput = "document.querySelector('div').innerText = s(this.value)"></textarea>
<div></div>


誰かがこれよりも良いスコアを獲得できることを願っています
Programmer5000

チャレンジは@ programmer5000を受け入れました
デビッドアーチボルド

@DavidArchibaldはすでに誰かがしましたが、新しい答えをいただければ幸いです。シリーズ3番目に興味がありますか?
Programmer5000

確かに。3があったことに気づかなかった
デビッドアーチボルド

2

PowerShell、80バイト

$args-split'\s|#'-ne''|%{$a+=(($i=[char[]]$_-join'+'|iex),-$i)[($x=!$x)]};$a-gt0

オンラインでお試しください!

(Pythonの回答の下でただきしむ。:D)

True左のパスとFalse右のパスの出力。

入力を、で区切られた文字列として取得します`n。これは、「リテラルバックスラッシュとnを含む文字列」に相当するPowerShell であるか、リテラルの複数行文字列です。次に、-splitその入力\s(改行を含む空白)または#空の結果をすべて除外する-ne''ため、数字の配列だけが残ります。それらはループに送られます|%{...}

各々の繰り返しは、まず現在の要素を取る$_、としてキャストcharアレイ、-joinそれを一緒にプラス記号で+、パイプそれにiex(略しInvoke-Expressionとに類似eval)。それはに格納される$iので、パスのこの特定のチャンクの数字を適切に合計します。次に($i, -$i)、それとその否定を配列の2つの要素として使用し、ブール値を前後に反転することでインデックスを付けます。つまり、このループの最初の反復、最初の左パスチャンク、にインデックスを付け-$iます。次回は取り$iます。等々。それらはに蓄積さ$a+=ます。

最後に、我々は、かどうかを評価$aされ-greater tハン0。大きい場合、右のパスの合計が大きくなり、そうでない場合、左のパスの合計が大きくなります。そのブール結果はパイプラインに残り、出力は暗黙的です。


2

CJam19 18バイト

qN/Sf%z{'1*:~:+}/>

オンラインでお試しください!

0左と1右に印刷します。

説明

q      e# Read all input.
N/     e# Split into lines.
Sf%    e# Split each line around runs of spaces.
z      e# Transpose to group each branch.
       e# Note that each branch will have the same number of digit segments
       e# now but the first branch will also have all the #s at the end in
       e# separate segments.
{      e# For each branch...
  '1*  e#   Join the segments into a single string with 1s as separators.
       e#   This will add the same number of 1s between digit segments in
       e#   both branches (which won't affect their relative sum) and it 
       e#   will also insert a 1 before each # in the first branch.
  :~   e#   Evaluate each character. The digit characters are simply turned
       e#   into their values, but # is the exponentiation operator in CJam.
       e#   This is why we inserted those additional 1s, because 1# is a no-op.
  :+   e#   Sum the digits in the branch.
}/
>      e# Check whether the left branch's sum is greater than the right one's.

1

Mathematica、80 77バイト

3バイトを節約してくれたMartin Enderに感謝します!

#<#2&@@Total@Partition[Tr/@ToExpression[Characters@StringSplit@#/."#"->0],2]&

改行で区切られた文字列を入力として受け取り、戻っTrueて左のパスFalseを取り、右のパスを取る純粋な関数。それらの長いMathematicaコマンド名を気にします; これは10トークンのようなものです。


0

ピップ19 18バイト

LR+XDax:-x+$+$0SGx

入力をコマンドライン上の単一の文字列として受け取ります(実際のコマンドラインで実行する場合は、引用符で囲んで改行をエスケープする必要があります)-1左、1右の出力。オンラインでお試しください!

説明

数字の連続をループし、集計に数字の合計を追加します。集計の符号は毎回交換され、その結果、左側の値が負になり、右側の値が正になります。次に、最終集計の記号(-1または1)を印刷します。

                    a is 1st cmdline arg; XD is regex `\d`; x is "" (implicit)
                    Note that "" in a math context is treated as 0
  +XD               Apply regex + to XD (resulting in `\d+`)
LR   a              Loop over matches of that regex in a:
             $0      Regex match variable containing the full match
           $+        Sum digits by folding on +
      x:-x+          Swap the sign of the tally and add this sum
               SGx  After the loop, print the sign of the tally

0

Haskell、64バイト

g=sum.map fromEnum
f(a:b:r)|a>"#"=g a-g b+f r|1<3=0
(>0).f.words

オンラインでお試しください!使用法:無名関数(>0).f.wordsは、改行で区切られた文字列を引数として受け取り、False左とTrue右に戻ります。

説明:

入力が与えられた

 99   989
  99  89
  99 99
    #
    #
   # 

それは文字列で" 99 989\n 99 89\n 99 99\n #\n #\n #"wordsすべての改行とスペースを取り除き、残りの文字列のリストを返します["99","989","99","89","99","99","#","#","#"]。この関数fは、最初の2つの要素abこのリストから取得aし、文字列「#」と比較することで数字の文字列かどうかを確認します。(char '#'はすべての数字char よりも小さいため'0''1'...数字で始まるすべての文字列が辞書的により大きくなります"#"。)関数は、gそのASCII文字コードに文字列内の各文字をマッピングし、その合計を返します。ではf、私たちは、適用gするabし、計算g a - g bの左パスマイナス右のいずれかの値の値であり、そしてへの再帰呼び出しに追加しますf次の行を処理します。左のパスがより多く移動された場合、結果はf負であり、そうでない場合は右のパスで正になるため(>0)、結果がゼロより大きいかどうかをチェックします。


0

Python 3、84バイト

現在のPythonの提出物はすべて関数なので、完全なプログラムに貢献すると思いました。

x=0
try:
 while 1:
  for n in input().split():x=-x+sum(map(int,n))
except:print(x>0)

True左のパスがあまり移動していFalseない場合に印刷します。オンラインでお試しください!

入力の各行に対して、これは空白で分割し、結果の各要素の数字を合計し、各ステップで集計の符号を反転しながら集計に追加します。それが有するもの当たるまで、入力の行を読み取る続ける#点はれる、map(int,n)例外が発生すると、我々は、印刷、ループを終了Trueタリーが正であればFalseそうでありません。


0

バッチ、169バイト

@echo off
set/as=0
:l
set/pr=
if not %r: =%==# call:c - %r%&goto l
cmd/cset/a"s>>9
exit/b
:c
call:r + %3
:r
set/as%1=%2%%10,d=%2/10
if %d% gtr 0 call:r %1 %d%

0左、-1右に印刷します。注:追加する数字を処理するサブルーチンを含む行が見つかるまで行を読み取り、最初の2つのパラメーターを処理するためにフォールスルーします。これは、のパラメータと左右の数字でサブルーチンを呼び出すと、右の数字が加算され、左の数字が減算されることを意味します。最後に、結果をシフトして符号を抽出します。#を停止します。パスの合計の差は511に制限されています(より大きな差をサポートするために1バイトを追加します)。各パスの各行に9桁以下(任意の数の行をサポート)。説明:dサブルーチンは2つのパラメーターを取ります:加算するか減算するか、および数字。最後の数字を10でモジュロで抽出し、残りの数字を10で除算して抽出し、残りの数字が残っている間に再帰的に呼び出します。cサブルーチンは3つのパラメータを取ります:加算または減算、数字が加算または減算し、さらに数字を追加するかどうか。それを呼び出しますdc-


0

オクターブ、46バイト

@(a)diff((a(:)-48)'*(bwlabel(a>35)(:)==1:2))<0

オンラインでお試しください!a入力として 2D文字配列を受け取る関数。

説明:

a=

    1   1  
     0   1 
      1   1
      1   1
      1   1
      1   1
       1 1 
        #  
        #  
        #  
         # 
          #

a > 35                   %convert the matrix to a binary matrix
                         %where there is a number corresponing
                         %element of the binary matrix is 1.

*   *  
 *   * 
  *   *
  *   *
  *   *
  *   *
   * * 

bwlabel(a>35)            %label each connected component. 


1   2  
 1   2 
  1   2
  1   2
  1   2
  1   2
   1 2 

B=bwlabel(a>35)(:)==1:2  % a binary `[n ,2]` matrix created 
                         % each column related to one of labels

A=(a(:)-48)'             % convert array of characters to array of numbers 

A * B                    % matrix multiplication that computes 
                         % the sum of numbers under each label

diff(A*B)<0              % check if the left is grater than the right

0

Java 7、219 216バイト

boolean c(String s){int l=0,r=0;for(String x:s.split("\n")){l+=f(x,0);r+=f(x,1);}return l>r;}int f(String x,int i){if(x.contains("#"))return 0;int n=0;for(int c:x.trim().split("\\s+")[i].getBytes())n+=c-48;return n;}

今回は52バイトより長いビット。;)
そして再びfalse右とtrue左に戻ります。

説明:

boolean c(String s){              // Method with String parameter and boolean return-type
  int l=0, r=0;                   //  Right and left counters
  for(String x : s.split("\n")){  //  Loop over de lines
    l += f(x,0);                  //   Add all left digits to the left-counter
    r += f(x,1);                  //   Add all right digits to the right-counter
  }                               //  End of loop
  return l>r;                     //  Return whether the left-counter is larger than the right-counter
}                                 // End of method

int f(String x, int i){           // Separate method with String and integer parameters, and int return-type
  if(x.contains("#"))             //  If the current line contains "#"
    return 0;                     //   Simply return 0
  int n=0;                        //  Counter
  for(int c :                     //  Loop over the digits by
              x.trim()            //    first removing leading and trailing whitespaces
              .split("\\s+")      //    then split them right in the middle
              [i]                 //    then pick either the left or right side based on the int index parameter
              .getBytes())        //    and convert that String to a byte-array
    n += c-48;                    //   For each of those digit-characters: add it to the counter
                                  //  End of loop (implicit / single-line body)
  return n;                       //  Return the counter
}                                 // End of separate method

テストコード:

ここで試してみてください。

class M{
  boolean c(String s){int l=0,r=0;for(String x:s.split("\n")){l+=f(x,0);r+=f(x,1);}return l>r;}int f(String x,int i){if(x.contains("#"))return 0;int n=0;for(int c:x.trim().split("\\s+")[i].getBytes())n+=c-48;return n;}

  public static void main(String[] a){
    M m = new M();
    System.out.println(m.c(" 1     2\n  1   2\n   1 2\n    #\n    #\n    #"));
    System.out.println(m.c(" 1     2\n  2   2\n   1 1\n    #\n    #\n    #"));
    System.out.println(m.c(" 12    2\n  11  2\n   1 1\n    #\n    #\n    #"));
    System.out.println(m.c(" 99   989\n  99  89\n  99 99\n  99 99\n    #\n    #\n    #\n   # "));
    System.out.println(m.c("1111 1110\n 001 111\n  11 11\n  11 11\n    #\n   ##\n  ##\n ##  "));
    System.out.println(m.c("1       1\n 0     1\n  1   1\n  1   1\n  1   1\n  1   1\n   1 1 \n    #\n    #\n    #\n     #\n      #"));
    System.out.println(m.c("1   1 \n 0   1 \n  1   1\n  1   1\n  1   1\n  1   1\n   1 1 \n    #\n    #\n    #\n     #\n      #"));
  }
}

出力:

false
false
true
false
false
false
false
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.