Дві дороги розходилися в жовтому лісі (частина 2)


25

Це друга в серії, третя - Дві дороги, розійшлися в жовтому лісі (частина 3)

Це ґрунтується на Дві дороги, розійшлися в жовтому лісі (частина 1) , попереднє завдання. Він був досить добре сприйнятий, але також був досить тривіальним (відповідь на Java в 52 байтах!), Тому я зробив щось складніше ...

Натхнення

Цей виклик натхненний відомою поемою Роберта Фроста "Дорога не взята":

Дві дороги розходилися в жовтому лісі,
І вибачте, що я не міг подорожувати обома
І бути однією мандрівницею, довго я стояв
І дивився вниз, наскільки я міг,
куди вона зігнулася в підліску;

... 2 абзаци оброблені ...

Я скажу про це зітханням
Десь віками і століттями, отже:
Дві дороги розійшлися в лісі, а я -
я взяв ту, яку менше проїжджав,
і це змінило все.

Зверніть увагу , що другий в останній рядок I took the one less traveled by,. Ваша мета - знайти найменш пройдений шлях у рядковому введенні. Ви повинні вивести одне з двох значень, які відрізняються одне від одного, тим сигналом, в який бік ви повинні повернути, щоб піти по дорозі, що не проїжджала. Після того, як доріжки доріг (слід шестикутників змінюється на цифри), ви знаходитесь на перехресті. Звідти будуть дві стежки, складені цифрами. Шлях, цифри якого мають найменшу суму, буде дорогою, яку не прийнято. Зауважте, що не взята дорога може мати більший шлях, але меншу суму шляху. Ось кілька прикладів / тестових випадків програми, яка друкує "ліворуч" або "праворуч" для не взятого шляху:

 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 по одному рядку, рядок, що містить символи LF, або рядок, що містить прямокутну косу рису і n. Якщо вам потрібно ввести будь-який інший спосіб, попросіть схвалення в коментарях.
  • Вам не доведеться турбуватися про недійсний вхідний або прив’язаний шлях. Вони ніколи не будуть введені у вашу програму / функцію.
  • Вхід може бути будь-якої довжини в ширину чи висоту, менший за межу рядка вашої мови.
  • Ніколи не буде а #та числа в одному рядку.
  • Усі цифри на шляху є натуральними цілими від 0 до 9.
  • Допускається введення або виведення з останнього нового рядка.
  • Дивіться мою відповідь JS ES6 нижче для прикладу.
  • Між двома стежками завжди буде не менше 1 місця.
  • Дві стежки завжди матимуть однакову висоту для кожної карти, але можуть бути різними на інших картах.
  • Якщо ви плутаєте конкретний тестовий випадок, будь ласка, скажіть мені.
  • 1111 інтерпретується як 1 + 1 + 1 + 1 = 4, а не 1111 = 1111. Карта - це ряд одноцифрових чисел, а не чисел довільної довжини.
  • Це , тому найкоротша відповідь у байтах виграє!
  • Стандартні лазівки заборонені

Якщо у вас є якісь запитання щодо цього виклику, запитайте мене в коментарях і удачі!


Гей, ви можете побачити всі відповіді та їх кількість байтів, вставивши $("div > h1").map(function(){return $(this).text()}).get().join("\n");у консоль!
програміст5000

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
A # - це не шестикутник ...
user253751

1
", але це також було досить тривіально (відповідь Java в 52 байтах!) " зараз 43 байти. ;)
Кевін Круїссен

Знову закриваєш? Що з тобою, на біса?
Меттью Рох

Відповіді:


2

05AB1E , 21 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 в пробіг N.

%r`1\G
-

Кожен рядок ( %), узгоджуйте послідовний ( \G) з кінця ( r) і замініть кожен на них- (тобто перетворіть праву гілку на -s).

Os`.

Сортувати всі символи, щоб усі - s були прямо перед усіма 1s.

+`-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внизу. (Вісім пар@ означає вісім біт, але найвищий біт є знаком, тому це рішення може вирішити максимальну різницю +127 або -128. Переповнення частини через це добре, якщо ми повернемося до завершення.)

Чотири рядки, які починаються так, як Ax]}#--..., читають введення, а у випадку цифри - відкидаючи його (за необхідності) та передаючи значення в суматори.

Перші три рядки вирішують, чи ми дивимося цифру чи послідовність пробілів, і відслідковуємо, чи потрібно заперечувати цифри.

Решта елементів, зафіксованих під входами, і елементи в крайній правій частині обробляють умову завершення та відображають вихід на ASCII (щоб ми отримали символи '0'або '1'замість значень 0x0або 0x1. Це ASCII-зіставлення не вимагало зайвих байтів, інакше я б не включили його.)


2
Мені подобається, що код виглядає як дві різні дороги.
Лайконі

@Laikoni Я навіть не помічав, це
якось

4

JavaScript (ES6), 55 байт

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

Мається на увазі немає кінцевих пробілів в кожному рядку, і виходів trueдля right, falseдля 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=на початку, оскільки вирази заборонені, лише функції, що зберігаються у вигляді змінної та цілих програм.
програміст5000

@ programmer5000 Чому? Здійснюється дещо дивне переопрацювання значень за замовчуванням, і це, схоже, не вказує на те, що це так у питанні.
Пшеничний майстер

1
@ programmer5000 Насправді неназвані функції дозволені за замовчуванням . (Спасибі за фрагмент, btw)
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?
програміст5000

@ 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>


Я сподіваюся, що хтось може отримати кращий бал, ніж цей ...
програміст5000

Виклик прийнято @ programmer5000
David Archibald

@DavidArchibald хтось уже зробив, але я би вдячний новій відповіді. Вас цікавить третя в серії ?
програміст5000

впевнений. Не зрозумів, що там 3
Девід Арчібальд

2

PowerShell , 80 байт

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

Спробуйте в Інтернеті!

(Тільки писк під відповіді Python.: D)

Виходи Trueдля лівого шляху та Falseдля правого шляху.

Вводиться як введення рядка з розмежуванням `n, що є еквівалентом PowerShell "рядка, що містить прямокутний ривок зворотної коси та n" , або як буквальний багаторядковий рядок. Потім ми вводимо -splitцей текст \s(пробіл, включаючи нові рядки) або #фільтруємо всі порожні результати -ne'', тому нам залишається лише масив цифр. Вони подаються в петлю|%{...} .

Кожну ітерацію ми спочатку беремо поточний елемент, передаємо $_його як charмасив, -joinразом зі знаком плюс +і передаємо на нього iex(короткий для Invoke-Expressionта подібний до eval). Це зберігається, $iтому ми правильно підсумовуємо цифри на цьому конкретному відрізку шляху. Тоді ми використовуємо це та його мінус як два елементи масиву ($i, -$i), індексовані на перегортання булевого значення вперед та назад. Значить, першу ітерацію через цю петлю, перший лівий фрагмент шляху, ми вкажемо на індекс -$i; наступного разу ми візьмемо $i; і так далі. Ті накопичені в $aс +=.

Нарешті, ми оцінюємо, чи $aє -gреатер- tхан 0. Якщо це так, то правий шлях мав більшу суму, інакше лівий шлях мав більшу суму. Булевий результат залишається на конвеєрі, а вихід неявний.


2

CJam , 19 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

Математика, 80 77 байт

Дякуємо Мартіну Ендеру за збереження 3 байтів!

#<#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бере перші два елементи aі bз цього списку і перевіряє, чи aє рядок цифр, порівнюючи її з рядком "#". (Оскільки '#'знак значень менше, ніж усі знаки числа будуть негативними та в іншому випадку позитивними для правильного шляху, значить'0' ,'1' ... кожен рядок , що починається з цифрою буде словниковий більше "#".) Функція gвідображає кожен символ в рядку з його кодом ASCII символів і повертає їх суму. У fзастосую gдо aі bі обчисліть g a - g b, тобто значення лівого шляху мінус значення правої, і додати його в рекурсивний викликfобробляти наступні рядки. Якщо лівий шлях більше пройдений, результат відf(>0) перевіряє, чи результат більший за нуль.


0

Пітон 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інакше.Спробуйте в Інтернеті!

Для кожного рядка введення це розділяється на пробіл, підсумовує цифри кожного результуючого елемента і додає його до підрахунку, перегортаючи знак підрахунку на кожному кроці. Він продовжує читати рядки введення до тих пір, поки не потрапить на один із знаком a #, після чого 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справа. Примітка. Читає рядки, поки не знайде один з а #, а потім перестає читати. Різниця в сумах шляху обмежена 511 (додайте 1 байт для підтримки більших відмінностей). Не більше 9 цифр у кожному рядку кожного шляху (підтримує будь-яку кількість рядків). Пояснення: Підпрограма для обробки цифр, яку слід додати, а потім проходить для обробки перших двох параметрів. Це означає, що виклик цифр і лівої, і правої цифр додасть праві цифри і відніме ліві цифри. Нарешті результат зміщується для отримання знака.d Підпрограма приймає два параметри: додавати чи віднімати та цифру (и). Він дістає останню цифру за модулем на 10, а решта цифр ділиться на 10 і називає себе рекурсивно, поки ще залишаються цифри. cПідпрограма приймає три параметри: потрібно чи додати або відняти, цифри , щоб додати або відняти, і додаткові цифри , щоб додати. Він називаєdc підпрограми з параметрами-


0

Октава, 46 байт

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

Спробуйте в Інтернеті! Функція, яка приймає 2D-масив символів aяк вхід.

Пояснення:

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
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.