Наскільки високі моноліти?


29

Ось приклад введення монолітів . У цьому прикладі є 4.

  _
 | |        _
 | |  _    | |
 | | | |   | |     _
_| |_| |___| |____| |_

Перший моноліт має висоту 4 одиниці, другий - 2, третій - 3, а останній - 1.

Завдання

Ваша програма повинна виводити висоти монолітів у порядку зліва направо. Формат виводу може бути в будь-якому виді списку або масиву.

Примітки

  • Вхід може бути прийнятий як будь-який розмірний рядок, список рядків або список символів.
  • Це , тому виграє найнижчий байт .
  • Ви повинні припустити, що моноліти завжди мають однакову ширину і завжди знаходяться як мінімум на _відстані один від одного.
  • Вони можуть виходити в будь-якій висоті і в будь-якій кількості.

I / O

  _
 | |        _
 | |  _    | |
 | | | |   | |     _
_| |_| |___| |____| |_   >> [4,2,3,1]

           _
          | |
  _       | |
 | |  _   | |  _
_| |_| |__| |_| |_   >> [2,1,4,1]


 _   _   _ 
| |_| |_| |_____   >> [1,1,1]

____________________   >> undefined behavior

 _
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |   >> [11]

     _       _       _       _       _
 _  | |  _  | |  _  | |  _  | |  _  | |
| |_| |_| |_| |_| |_| |_| |_| |_| |_| |  >> [1,2,1,2,1,2,1,2,1,2]

2
Чи можу я припустити, що введення правильно зафіксовано пробілами?
isaacg

17
Чи [10]не є ваш моноліт [11]?
TessellatingHeckler

Чи не визначився б лише порожній масив?
Соломон Учко

@isaacg так, це було б добре
Гравітон

@SolomonUcko технічно так, хоча для спрощення всіх мов я вирішив не мати з ними справи.
Гравітон

Відповіді:


15

Желе , (8?) 9 байт

Ỵ=”|Sḟ0m2

Монадічне посилання, що приймає список символів як зазначений і повертає список цілих чисел.

Примітка: 8 байт, якщо список рядків, по одному на рядок, справді мав бути дозволеним форматом введення - просто видаліть .

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

Як?

Ỵ=”|Sḟ0m2 - Link: list of characters, s
Ỵ         - split at newlines
  ”|      - literal '|'
 =        - equals (vectorises)
    S     - sum (vectorises, hence counts the number of '|' in every column)
     ḟ0   - filter out zeros (only keep the results from the sides of the towers)
       m2 - modulo index with 2 (keep only the left side measurements)

Я не знаю, але це добре?
В. Куртуа

1
@ V.Courtois Я не бачу, чому б ні, оскільки ми, мабуть, ніколи не отримаємо такого вкладу.
Ерік Аутгольфер

Гаразд, це тому, що я побачив, що деякі інші відповіді приймають це підрахунок
В. Куртуа

2
@ V.Courtois запропонований вами вклад не відповідає специфікаціям, аналогічно додавання підкреслень у небі, моноліт чи побічний шлях, або під землею, ймовірно, порушить багато інших даних.
Джонатан Аллан

Виборця - не хотіли б ви пояснити свої причини?
Джонатан Аллан


6

JavaScript (ES6), 79 78 байт

-1 байт завдяки @Shaggy

a=>a.map((b,i)=>b.replace(/_/g,(_,j)=>o[j]=a.length-i-1),o=[])&&o.filter(x=>x)

Приймає введення як масив рядків.

Тест-фрагмент

f=
a=>a.map((b,i)=>b.replace(/_/g,(_,j)=>o[j]=a.length-i-1),o=[])&&o.filter(x=>x)
I.value="           _\n          | |\n  _       | |\n | |  _   | |  _\n_| |_| |__| |_| |_"
<textarea id=I rows=7 cols=30></textarea><br><button onclick="O.value=`[${f(I.value.split`\n`).join`, `}]`">Run</button> <input id=O disabled>


1
78 байт:a=>a.map((x,y)=>x.replace(/_/g,(_,z)=>c[z]=a.length-y-1),c=[])&&c.filter(n=>n)
Кудлатий

@Shaggy Приємно, я зовсім не думав використовувати replace. Спасибі!
Джастін Марінер

6

C ++, 171 169 байт

#import<vector>
#import<iostream>
int f(std::vector<std::string>s){for(int a,j,i=0,k=s.size()-1;a=s[k][i];++i)if(a==32){for(j=0;(a=s[k-++j][i])-95;);std::cout<<j<<" ";}}

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

C ++ (GCC), 150 байт

Дякуємо @aschepler!

#import<vector>
#import<iostream>
int f(auto s){for(int a,j,i=0,k=s.size()-1;a=s[k][i];++i)if(a==32){for(j=0;(a=s[k-++j][i])-95;);std::cout<<j<<" ";}}

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


1
Якщо ви використовуєте g ++, ви можете використовувати нестандартний f(auto s)та вказати, що він приймає будь-який контейнер з випадковим доступом для контейнерів з випадковим доступом char.
aschepler


5

Діалог APL, 29 байт

{0~⍨↑+/(⌈/⍴¨⍵)↑¨(⍳≢⍵)×⌽⍵='_'}

Бігайте з ⎕IO←0.

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

Як?

⌽⍵='_'- де є '_', першими верхніми рядками

×- помножити на ...

(⍳≢⍵)- діапазон (індексований нулем)

↑¨ - для кожного рядка, майданчик із нулями по ...

(⌈/⍴¨⍵) - максимальна довжина

↑+/ - підсумовуйте рядки, застебнуті та сплющені

0~⍨ - знімає нулі



5

PowerShell, 133 байт

param($s)$r=,0*($l=($s=$s-replace'\| \|',' 1 ')[0].Length);1..$s.Count|%{$z=$_-1;0..($l-1)|%{$r[$_]+=(''+$s[$z][$_]-as[int])}};$r-ne0

Схоже, це не дуже конкурентоспроможно; він робить регекс заміною, щоб перетворити вежі в стовпці 1, робить масив 0 довжиною вхідного рядка, а потім кроки через рядки, складаючи 1s.

Тести готові до запуску:

$s1 = @'
  _                   
 | |        _         
 | |  _    | |        
 | | | |   | |     _  
_| |_| |___| |____| |_
'@-split"`r?`n"


$s2 = @'
 _
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | 
'@-split"`r?`n"

$s3 = @'
           _      
          | |       
  _       | |           
 | |  _   | |  _   
_| |_| |__| |_| |_ 
'@-split"`r?`n"


$s4 = @'
 _   _   _      
| |_| |_| |_____ 
'@-split"`r?`n"

$s5 = @'
     _       _       _       _       _ 
 _  | |  _  | |  _  | |  _  | |  _  | |
| |_| |_| |_| |_| |_| |_| |_| |_| |_| | 
'@-split"`r?`n"

4

Japt , 11 байт

z ·mb'_ fw0

Перевірте це в Інтернеті!

Пояснення

z ·mb'_ fw0   : Implicit input
z             : Rotate the input clockwise. This puts the "floor" against the left side.
  ·           : Split the 2D string into lines.
   m          : Replace each column (now row) X with
    b'_       :   the index of '_' in X (0-indexed). This gives us the output list, with
              :   0's and -1's mixed in representing the columns that are not monoliths.
        f     : Take only the items X where
         w0   :   max(X, 0) is truthy. Since 0 is falsy, this removes anything <= 0.
              : Implicit: output result of last expression

4

Сітківка , 48 38 байт

^
¶
{`(¶.*)*¶_(.*¶)+
$#2 $&
}`¶.
¶
G`.

Спробуйте в Інтернеті! Посилання включає перший приклад. Пояснення: рядок є префіксом, який збиратиме результати. Оскільки кожен стовпчик неодноразово видаляється, ті, що містять _надземний рівень, мають кількість залишкових рядків у стовпці. Нарешті порожні рядки видаляються. Редагувати: Збережено 10 байт завдяки натхненню від @FryAmTheEggman.


Приємно, у мене було трохи коротше рішення , але воно не працюватиме на великих входах, оскільки це зіпсує мою здатність до їх сортування. Перехід колонки за стовпцем - це приємний спосіб уникнути цього!
FryAmTheEggman

@FryAmTheEggman Я перейшов до вашого методу підрахунку рядків за допомогою _s, який має набагато більше сенсу, ніж намагатися використовувати |s, дякую!
Ніл

@FryAmTheEggman Не виправляє проблему, але ваш етап сортування можна спростити, відкинувши панель пошуку та сортування $.%`, і завершальним етапом може бути !`\d+. І якщо ви змінили перший етап на пошук, вам не потрібно робити цикл.
Мартін Ендер

@FryAmTheEggman І ось виправлення вашого підходу, але воно закінчується в 46 байт.
Мартін Ендер

@MartinEnder 45 можливо? Спробуйте в Інтернеті!
Ніл

4

Java 8, 133 117 116 114 байт

a->{for(int l=a.length-1,i=0,j;i<a[0].length;i++)if(a[l][i]<33){for(j=0;a[j][i]<33;j++);System.out.print(l-j+",");}}

Приймає введення як (← економить 16 байт). -2 байти в обмін на менш читаний вихід завдяки @ OlivierGrégoire , змінивши на .String[] char[][]
print(l-j+",")println(l-j)

Пояснення:

Спробуйте тут.

a->{                         // Method with character 2D-array parameter and no return-type
  for(int l=a.length-1,      //  Length of the 2D char-array - 1
      i=0,j;                 //  Index-integers
    i<a[0].length;i++)       //  Loop (1) over the 2D char-array
    if(a[l][i]<33){          //   If the base of the current column is a space
      for(j=0;a[j][i]<33;    //    Loop (2) over the cells in this column as long as
                             //    we encounter spaces (from top to bottom)
        j++                  //     And increase `j` every time, to go down the column
      );                     //    End of loop (2)
      System.out.println(l-j);
                             //    Print the amount of rows - `j`
    }                        //   End of if-block
                             //  End of loop (1) (implicit / single-line body)
}                            // End of method

Я ще не пробував цього, але моя ідея для цього виклику полягала в тому, щоб перейти зверху вниз і шукати, _чи знайдений магазин у ньому, а потім замовити на це, ігноруючи нижній ряд, звичайно. Може допомогти врятувати байти ...
TheLethalCoder

@TheLethalCoder Це також було моєю початковою думкою, але де ви хочете її зберігати / замовляти? Спочатку я думав про карту, але вони несортовані, тому вам знадобиться LinkedMap. У моїй голові все це звучало трохи забагато байтів, але якщо ви зможете знайти спосіб досягти цього коротше, ніж це, не соромтеся опублікувати відповідь, і я поставив це +1. :)
Кевін Кройсейсен

Мені вдалося лише знизити його до 150, використовуючи Linq, але все ж має бути місце для гольфу.
TheLethalCoder

У C # у нас є багатовимірні масиви на зразок: new[,]замість зубчастого масиву ви використовуєте як new[][]. Якщо у вас це є в Java, це може заощадити кілька байт.
TheLethalCoder

1
System.out.println(l-j);Здається, мені достатньо списку, щоб зберегти 2 байти. Крім того , в поясненні, ви забули змінити length()в length(без падіння на байт-лічильник , як це правильно в поданні).
Олів'є Грегоар

3

Haskell, 75 74 байти

import Data.List;f=filter(>0).map(length.fst.span(<'!').reverse).transpose

Вхід очікується як список рядків (rowwise).


Навіщо використовувати крапку з комою після імпорту, коли новий рядок такої ж довжини та ідіоматичний?
Жуль

@Jules: Так, зазвичай роблю
siracusa




3

C #, 150 144 137 байт

using System.Linq;a=>a.SelectMany((i,h)=>i.Select((c,w)=>new{c,w,d=a.Length-1-h}).Where(o=>o.c==95&o.d>0)).OrderBy(o=>o.w).Select(o=>o.d)

Повна / відформатована версія:

using System;
using System.Collections.Generic;
using System.Linq;

class P
{
    static void Main()
    {
        Func<char[][], IEnumerable<int>> f = a =>
            a.SelectMany((i, h) => i.Select((c, w) => new { c, w, d = a.Length - 1 - h })
                                    .Where(o => o.c == 95 & o.d > 0))
             .OrderBy(o => o.w)
             .Select(o => o.d);

        Console.WriteLine(string.Concat(f(new char[][]
        {
            "  _                 ".ToArray(),
            " | |       _        ".ToArray(),
            " | |  _   | |       ".ToArray(),
            " | | | |  | |    _  ".ToArray(),
            "_| |_| |__| |___| |_".ToArray(),
        })));

        Console.ReadLine();
    }
}

3

Java 8 - 229 байт 213 байт

s->{Map<Integer,Integer> m=new TreeMap();String[] l=s.split("\n");for(int i=0,j=-1;i<l.length-1;++i){s=l[i];while((j=s.indexOf("_",j+1))>=0){m.put(j,i);}}for(int i:m.values()){System.out.print(l.length-i-1+",");}}

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

Безголовки:

public static void foo(String input)
{
    Map<Integer, Integer> map = new TreeMap(); // Raw types!!
    String[] lines = input.split("\n");

    for (int i = 0, j = -1; i < lines.length - 1; ++i)
    {
        input = lines[i];

        while ((j = input.indexOf("_", j + 1)) >= 0)
        {
            map.put(j, i);
        }
    }

    for(int i:map.values())
    {
        System.out.print(lines.length - i - 1 + ",");
    }
}

Ву, перший пост. Будь-яка допомога в її покращенні була б чудовою. Я знаю, що можу позбутися indexOfнаписаного двічі. Знав це! Я грав з ідеєю зміни типів на карті з Integer на Long, але думаю, що це глухий кут.


Я знаю, що є вже набагато краще рішення Java 8 , але це бере char[][]вклад, з яким я думаю, що в цьому випадку простіше працювати, ніж String.


1
Ви не включили імпорт (вони потрібні для відповідей на Java). Не використовуйте а, Mapале int[](можливо, ініціалізований до new int[99]?). Не потрібно місця після String[] l: String[]lпрацює так само і коротше. Використовуйте println(l.length-i-1)замість println(l.length-i-1+","). Чи не ініціалізації j: просто написати: ,j;. Якщо ви використовуєте int[]як було запропоновано раніше, заявіть так: int m[]=new int[99],i=0,j;і видаліть декларацію з for-loop.
Олів'є Грегоар

1
OlivierGrégoire дійсно має рацію щодо необхідного імпорту для Map. Що стосується деяких гольф вашого поточного коду з картою, ви можете змінити його до цього: import java.util.*;s->{Map m=new TreeMap();String[]a=s.split("\n");int l=a.length-1,j=-1,i=j;for(;++i<l;)for(s=a[i];(j=s.indexOf("_",j+1))>=0;m.put(j,i));for(Object o:m.values())System.out.println(l-(int)o);}. Немає необхідності складати <Integer,Integer>карту, коли ви можете її робити int; a.length-1використовується двічі, тому ви можете використовувати змінну; помістивши всередину for-петлі, ви зможете позбутися всіх дужок. О, і ласкаво просимо до PPCG! :)
Kevin Cruijssen

@KevinCruijssen Дякую! Перетворення вмісту першої для циклу в тіло для циклу було натхненним! Супер розумний.
Майкл

@Michael Безкоштовно :) О, і якщо ви цього ще не бачили: Поради щодо гольфу на Яві та Поради щодо гольфу на <всіх мовах> можуть бути цікавими для прочитання. Допомагав мені дуже багато, коли я вперше почав (і все ще іноді).
Kevin Cruijssen


2

Математика, 48 47 39 байт

Last/@(Reverse@Most@#~Position~"_")&

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

Functionякий очікує прямокутний масив символів. Займає Mostмасив (усі, крім останнього рядка), Reverses, потім бере Transpose*, а потім знаходить усі Positions, на яких _з'являється символ. Відповідні висоти є Lastелементами кожної Position.

* - 3символ байта приватного використання, U+F3C7який представлений \[Transpose]у Mathematica. Зауважте, що це не працює в Mathics , тому посилання TIO просто використовує Transpose.


2

SOGL V0.12 , 9 байт

I{ _WH╥?O

Спробуйте тут!
Приймає введення як масив масивів рядків (символів).

Пояснення:

I          rotate the array clockwise
 {         for each element
   _       push "_"
    W      get its index in the array (0 if not found, 1 if its the ground, >1 if its what we need)
     H     decrease that
      ╥    palindromize (duplicates the number, if it's <0, then errors and pushes 0, if =0, pushes 0, if >0, then pushes the number palindromized (always truthy))
       ?   if that, then
        T  output in a new line the original decreased index

2

JavaScript (ES6), 108 104 88 байт

Збережено 16 байт завдяки @JustinMariner

i=>i.map((s,h)=>{while(t=r.exec(s))m[t.index]=i.length-h-1},m=[],r=/_/g)&&m.filter(e=>e)

Введення приймається як масив рядків

let input = [
'  _',
' | |           _',
' | |  _   _   | |',
' | | | | | |  | |     _',
'_| |_| |_| |__| |____| |_'
]

let anonymousFunction =
i=>i.map((s,h)=>{while(t=r.exec(s))m[t.index]=i.length-h-1},m=[],r=/_/g)&&m.filter(e=>e)

console.log(anonymousFunction(input))



Дякую @JustinMariner! Я прихильний до ініціалізації змінної як невикористаних параметрів, що надаються Array.map, це класна хитрість.
alexanderbird

Вам дійсно потрібно призначити RegEx змінній? Ви можете використовувати його безпосередньо в execі зберегти кілька байтів.
Кудлатий

Насправді, це потрібно - цикл у той час, коли перетворюється на кожну відповідність лінії, і без внутрішнього стану регулярного вираження у змінній він би відповідав першому повороту щоразу і циклу нескінченно. Кожна ітерація створювала б нове регулярне вираження, щоб воно execвідповідало першому. Він фактично виходить з ладу редактор фрагментів обміну стеками, якщо ви вбудовуєте регулярний вираз. Якщо я щось не пропускаю?
alexanderbird

@shaggy Я забув позначити вас у своєму останньому коментарі
alexanderbird

2

CJam, 15 14 байт

1 байт збережено завдяки @BusinessCat

{W%z'_f#{0>},}

Це блок, який приймає масив рядків на стеку і виводить масив.

Пояснення:

W%    e# Reverse
z     e# Zip
'_f#  e# Get the index of '_' in each element (-1 if not found)
{0>}, e# Filter where positive

Ви можете зберегти 1 байт, обернувши весь масив перед транспозицією.
Ділова кішка

1

Піп , 18 17 байт

15 байт коду, +2 для -rpпрапорів.

_FI_@?'_MRVgZDs

Бере вхід з stdin. Спробуйте в Інтернеті!

Пояснення

                 g is list of lines from stdin (-r flag); s is space
         RVg     Reverse g
            ZDs  Zip (transpose), filling gaps with a default char of space
        M        Map this function:
   _@?'_          Index of _ in each line (or nil if it doesn't appear)
_FI              Filter, keeping only the truthy (nonzero, non-nil) values
                 Autoprint in repr format (-p flag)



1

Perl 6 , 65 байт

{m:ex/^^(\N+)_([\N*\n]+:)/.sort(*[0].chars).map(+*[1].comb("
"))}

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

  • m:exhaustive/^^(\N+)_([\N*\n]+:)/здійснює пошук у вхідному рядку для всіх підкреслень і повертає об'єкт відповідності для кожної, де перші круглі дужки містять попередню частину рядка, в якій знайдено підкреслення, а друга, що записує круглі дужки, містять весь решта рядка. Решта рядка повинна містити принаймні один новий рядок, тому ми не рахуємо підкреслення на рівні землі. :exhaustiveПрапор дозволяє ці матчі з перекриттям.
  • .sort(*[0].chars)сортує ці об'єкти відповідності за кількістю символів у частині рядка, що передує кожному підкреслення. Це вказує їм зліва направо.
  • .map(+*[1].comb("\n"))відображає кожен об'єкт відповідності на кількість символів нового рядка у частині вхідного рядка, що спирається на кожен підкреслення - тобто висоту. Це \nфактичний символ нового рядка, зберігаючи один байт.

0

PHP, 119 байт

function($s){$r=array_map(null,...$s);foreach($r as$k=>&$v)if($v=array_count_values($v)['|'])echo($v+$r[$k+2]=0)." ";};

Давайте розбимо це! Нашим вводом тут є двовимірний масив символів.

$r=array_map(null,...$s) // Neat little snippet to transpose the array

foreach($r as$k=>&$v)    // Loop through the array, grabbing each row of our 2D array 
(which is now each column of the monolith)

if($v=array_count_values($v)['|']) // Count the number of '|' characters in the column 
(which is the height of our monolith), and if it's greater than 0 (truthy in PHP)...

echo($v+$r[$k+2]=0)." "; // Output that number, and simultaneously set the row 2 indices
                            down to null (to remove duplicate values)

-1

Бере в рядок багаторядкових. Кредит за налаштування (колонтитул та колонтитул) належить @GarethPW

Python 2 , 29 байт

lambda s:len(s.split('\n'))-1

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

Це просто розділить масив на нову лінію та довжину повернення-1.


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