Виріжте квадрат з нитки


21

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

Квадратний рядок - це той, де:

  • Кожен рядок має однакову кількість символів
  • Кількість символів у кожному рядку дорівнює кількості рядків.

Розглянемо наступний можливий рядок введення:

abcde
fgh
asdf
foobar

Найбільший квадрат, який ви можете взяти з нього, який включає перший символ ( aу верхньому куті):

abc
fgh
asd

Не може бути квадрата довжини сторони 4, оскільки другий рядок недостатньо довгий. Тепер розглянемо цей потенційний внесок:

a
bcd
edf
ghi

Найбільша площа тут просто a. Квадрат 3x3, сформований внизу, не містить самого першого символу і не рахується.

Ось ще кілька тестових випадків:

a

a

abc
def
gh

ab
de

ab
cd

ab
cd

abcde
fghij
klm
no

abc
fgh
klm

a
b

a

Ви можете вимагати, щоб введення було обмежене вибором LF, CR або CRLF.

Символи (символи) нового рядка не вважаються частиною довжини рядка.

Ви можете вимагати, щоб у введенні був новий або наступний рядок, який не враховується як додатковий рядок.

Вхід - це рядок або 1D масив char; це не список рядків.

Ви можете припустити, що введення не порожнє, і всі рядки є не порожніми, і що він містить лише друкований ASCII, включаючи пробіли та нові рядки (для роздільника рядків), але не вкладки.

Це , найменше виграш байтів!



5
+1 за цікавий виклик, -1 для суворого вводу-виводу
Денніс

@Денніс не кожне рішення потрібно використовувати, .split('\n')тому я не розумію, чому деякі повинні отримати його безкоштовно.
Павло

2
Справа не в тому, що потрібно додавати байти для нудної котлової панелі. Деякі підходи (наприклад, рекурсивні функції) стають абсолютно непрактичними, якщо є попередня або післяобробка.
Денніс

@Dennis Я не думав про це так. Як ви думаєте, я повинен зараз це змінити, чи вже пізно?
Павло

Відповіді:


5

Брахілог , 11 байт

ṇ⊇ᵐẹa₀ṁcᵐ~ṇ

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

Пояснення

ṇ             Split on linebreaks
 ⊇ᵐ           Take a subset of each line
   ẹ          Split the lines into list of chars
    a₀        Take a prefix of this list of lists of chars
      ṁ       It is a square matrix
       cᵐ     Concatenate the list of chars back into strings
         ~ṇ   Join the strings with linebreaks

Хороша робота над найкоротшим рішенням (поки що), Брахілог впевнений, що любить квадрати, чи не так?
Павло

@Pavel Вбудований дійсно дуже зручний!
Фаталізувати

7

Лушпиння , 13 байт

►oΛ≈S+TzṀ↑Nḣ¶

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

Пояснення

►oΛ≈S+TzṀ↑Nḣ¶  Implicit input, say "ab\nc".
            ¶  Split at newlines: ["ab","c"]
           ḣ   Take prefixes: [["ab"],["ab","c"]]
       z  N    Zip with [1,2,3..
        Ṁ↑     by taking that many characters from each row: [["a"],["ab","c"]]
►o             Find rightmost element that satisfies this:
  Λ            all strings in
    S+T        the list concatenated to its transpose
   ≈           have the same length: ["a"]
               Implicitly print separated by newlines.

1
Як це навіть мова програмування - ви щойно вклеїли деякі незрозумілі символи унікоду! ;)
ріпа

1
@Petar Ласкаво просимо у світ мов з гольфу, які створені спеціально для використання якомога менше байтів для виконання певного завдання. Частина цього полягає у створенні користувацької кодової сторінки, щоб перед кожним можливим байтом був символ, замість звичайних 95 друкованих ASCII. Але не хвилюйтеся, є також набагато більш розбірливі мови для гри в гольф; наприклад мій запис MATL [/ безсоромне самореклама]
Sanchises

5

GNU sed , 106 + 1 94 + 2 = 96 байт

+2 байти для -rzпрапорів. Використовується недруковані символи NUL та BEL, показані як @і #тут. Дивіться нижче для скиду xxd.

Дякуємо @seshoumara за те, що він направив мене вниз по шляху -z.

s/^/@/gm
s/.*/#&\n/
:B
s/@(.)/\1@/mg
s/#(.+\n)/\1#/m
/#.*@./M!b
/@\n.*#/!bB
:
s/@[^\n]*|#.*//g

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

Пояснення

Це працює, вставляючи в текст два курсори - один для переходу рядків і один перехід стовпців. Курсори представлені відповідно NUL (0x00) та BEL (0x07), але в наведених нижче прикладах я буду використовувати @і #. Припустимо, у нас є цей вхід:

abcde
fgh
asdf
foobar

Курсор BEL вставляється перед 0-м стовпцем, а курсор BEL перед 0-м рядком (тут я тримав стовпці вирівняними для розбірливості; але фактично немає лівої прокладки):

#@abcde
 @fgh
 @asdf
 @foobar

У циклі курсори переміщуються на один символ праворуч і на одну лінію вниз відповідно:

 a@bcde
#f@gh
 a@sdf
 f@oobar
 ab@cde
 fg@h
#as@df
 fo@obar
 abc@de
 fgh@
 asd@f
#foo@bar

Після кожної ітерації він перевіряє дві умови:

  1. Чи є в рядку з курсором рядка курсор стовпця і чи може курсор стовпця переміщуватися праворуч?
  2. Чи може кожен курсор стовпця переміщуватися вправо?

Якщо будь-яка умова хибна, цикл закінчується. Сценарій закінчується, видаляючи все після@ кожного рядка та все після #в просторі шаблону.

xxd звалище

00000000: 732f 5e2f 002f 676d 0a73 2f2e 2a2f 0726  s/^/./gm.s/.*/.&
00000010: 5c6e 2f0a 3a42 0a73 2f00 282e 292f 5c31  \n/.:B.s/.(.)/\1
00000020: 002f 6d67 0a73 2f07 282e 2b5c 6e29 2f5c  ./mg.s/.(.+\n)/\
00000030: 3107 2f6d 0a2f 072e 2a00 2e2f 4d21 620a  1./m./..*../M!b.
00000040: 2f00 5c6e 2e2a 072f 2162 420a 3a0a 732f  /.\n.*./!bB.:.s/
00000050: 005b 5e5c 6e5d 2a7c 072e 2a2f 2f67       .[^\n]*|..*//g

Ви можете вилучити перший цикл, A, оскільки у висловлюванні зазначено, що ви повинні прочитати введення як рядок, щоб ви могли отримати "line1 \ nline2 \ nline3" і т.д. Інші відповіді теж зробили це. Це повинно отримати кількість нижче 100 :)
seshoumara

@seshoumara Інші відповіді робити , line1\nline2\nline3де \nце \x5C\x6E? Котрий?
Йорданія

Ви можете мені надати посилання? (Клацніть на "поділитися" внизу будь-якої відповіді.) Або покажіть мені в TiO, що ви маєте на увазі? У всіх відповідях Python та PHP, які я бачу \n, інтерпретується як символ нового рядка ( \x0A, ні \x5C\x6E), і я не можу знайти спосіб змусити sed приймати введення символів нового рядка як єдиний рядок.
Йорданія

@seshoumara Ха, ніколи, я просто згадав -zпрапор. Спасибі!
Йорданія

4

Python 2 , 81 байт

l=input().split('\n')
i=0
while zip(*l[:i+1])[i:]:i+=1
for x in l[:i]:print x[:i]

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


Цікавий метод, але на 2 байти довше.

Python 2 , 83 байти

l=input().split('\n')
while len(zip(*l))<len(l):l.pop()
for x in l:print x[:len(l)]

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


1
Чи не inputчитає лише один рядок?
Павло

@Pavel, якщо ви подивитесь на приклад в Інтернеті, ви можете побачити, що він використовує явні символи нового рядка, щоб зберегти введення однорядним рядком. Можливо, вибрали цей метод, тому raw_input()що додали б більше байтів.
Ксав'є Дасс

4

JavaScript (ES6), 77 байт

f=(s,i=1,m=s.match(`^${`(.{${i}}).*
`.repeat(i)}`))=>m?f(s,i+1)||m.slice(1):0

Рекурсивно використовує регулярний вираз для пошуку більшого і більшого квадрата, поки жоден не буде знайдений.

Регулярним виразом буде такий квадрат 3x3:

^(.{3}).*
(.{3}).*
(.{3}).*

Очікується, що введення закінчиться новим рядком, а вихід - списком.

Пояснення:

f = (s,                                            //input
     i = 1,                                        //start searching for a 1x1 square
     m = s.match(`^${`(.{${i}}).*\n`.repeat(i)}`)  //match on the regex
    )=>
    m ? f(s, i+1)                   //if there's a match, recurse on the next-sized square
        || m.slice(1) :             //if there's not a next-sized square, return the match
        0                           //no match for this square, so stop recursing

Фрагмент:




3

R , 84 83 81 76 байт

-5 байт, що передають підхід Денніса сsum

cat(substr(x<-readLines(),1,m<-sum(cummin(nchar(x))>=seq(x)))[1:m],sep='\n')

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

читає з stdin, друкує до stdout без зворотного нового рядка.

Трохи незворушений:

x <- readLines()                    # read in input one line at a time;
                                    # saved as a vector of strings
minChar <- cummin(nchar(x))         # rolling minimum of all line lengths
lineNum <- seq(x)                   # line number
mins <- minChar>=lineNum            # the min between the line number and the line lengths
m <- sum(mins)                      # the sum of those is the size of the square
cat(substr(x,1,m)[1:m],sep='\n')    # print the first m characters of the first m lines,
                                    # and join with newlines


3

C (gcc) , 162 159 151 147 144 142 137 137 байт

Тут повинні бути кілька ударів для гольфу ...

i,l=9;char*p,s[9][8];main(t){for(p=s;~(*p=getchar());)p=*p<32?*p=0,l=(t=strlen(s+i))<l?t:l,s[++i]:p+1;for(i=0;i<l;puts(s+i++))s[i][l]=0;}

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


Можуть !=-1бути >-1чи мають getchar()вихідні значення менше мінус одного? Чи може це навіть бути +1?
Джонатан Фрех

Потенціал 158 байт .
Джонатан Фрех

@JonathanFrech Я можу використовувати ~для виявлення мінус один.
cleblanc

1
@RickHitchcock Здається, працює в останній версії для гольфу.
cleblanc

2

Желе , 15 байт

L€«\‘>Jx@Z
ỴÇÇY

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

Як це працює

ỴÇÇY        Main link. Argument: s (string)

Ỵ           Split s at linefeeds, yielding a string array.
 Ç          Apply the helper link.
  Ç         Apply the helper link again.
   Y        Join, separating by linefeeds.


L€«\‘>Jx@Z  Helper link. Argument: A (string array/2D character array)

L€          Compute the length of each row/line.
  «\        Take the cumulative minimum.
    ‘       Increment each minimum.
      J     Indices; yield [1, ..., len(A)].
     >      Perform elementwise comparison. If the output should have n lines, this
            yields an array of n ones and len(A)-n zeroes.
         Z  Zip/transpose A.
       x@   For each string t in the result to the right, repeat its characters as
            many times as indicated in the result to the left, discarding all but
            the first n characters.

2

Java 8, 150 байт

s->{String q[]=s.split("\n"),r="";int l=q[0].length(),i=0,t;for(;i<l;l=t<l?t:l)t=q[i++].length();for(i=0;i<l;)r+=q[i++].substring(0,l)+"\n";return r;}

Пояснення:

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

s->{                          // Method with String as both parameter and return-type 
  String q[]=s.split("\n"),   //  Split the input on new-lines, and put it in an array
         r="";                //  Result-String, starting empty
  int l=q[0].length(),        //  Length of the lines, starting at the length of line 1
      i=0,                    //  Index-integer, starting at 0
      t;                      //  Temp integer
  for(;i<l;                   //  Loop (1) from 0 to `l` (exclusive)
      l=t<l?                  //    After every iteration: if `t` is smaller than `l`:
         t                    //     Change `l` to `t`
        :                     //    Else:
         l)                   //     Leave `l` the same
    t=q[i++].length();        //   Set `t` to the length of the current line
                              //  End of loop (1) (implicit / single-line body)
  for(i=0;i<l;                //  Loop (2) from 0 to `l` (the determined square dimension)
    r+=                       //   Append the result-String with:
       q[i++].substring(0,l)  //    The current row chopped at `l-1`
       +"\n"                  //    + a new-line
  );                          //  End of loop (2)
  return r;                   //  Return the result-String
}                             // End of method

2

MATL , 33 байти

10-~ft1)wdhqY<tn:vX<X>:GYbowt3$)c

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

Моє почуття-павук говорить про те, що, мабуть, існує коротший шлях (я думаю про щось з Yboсамого початку) ... Потрібен новий рядок наприкінці. (Примітка. Я трохи переробив це, оскільки це також буде обробляти порожні рядки, що не потрібно. Я побачу, чи можу я зменшити кількість рахунків, тому що в коді гольф - це не особливість, а помилка)


1
@Pavel Guiseppe мав на увазі іншу версію, яку я відкотив, тому що в ній справді була помилка.
Санчіз



1

JavaScript (ES6), 95 байт

f=
s=>(g=s=>s.slice(0,a.findIndex((e,i)=>a.some((s,j)=>j<=i&!s[i]))))(a=s.split`
`).map(g).join`
`
<textarea oninput=o.textContent=f(this.value+`\n`)></textarea><pre id=o>

Потрібна нова введення рядка.



1

APL (Діалог) , 25 байт *

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

(↑↑⍨2⍴(⌊/≢,≢¨))⎕AV[3]∘≠⊆⊢

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

Це дійсно вершина двох незалежних функцій, а саме, ⎕AV[3]∘≠⊆⊢яка стосується незручного формату введення та ↑↑⍨2⍴(⌊/≢,≢¨)яка робить справді цікаву роботу.

⎕AV[3]∘≠ відмінність від LF (третій елемент A tomic V ector - набір символів)

 розділи (підрядки, що починаються зі значень, більших від попередника, і падають на 0s)

 аргумент

() Застосувати таку негласну функцію:

2⍴() Переформатуйте наступне на довжину 2:

  ⌊/ мінімум

   кількість рядків

  , слідом за ним

  ≢¨ кількість символів у кожному рядку

↑⍨ взяти стільки рядків і стовпців із

 рядки змішуються разом, щоб утворити матрицю (оббивка з пробілами)


* У Classic with ⎕ML( M igration L evel) 3(за замовчуванням для багатьох систем) та заміщенням для та для лівих лівих . Тіо!


Якщо в Dyalog Classic це однакова довжина, ви можете сказати, що це Dyalog Classic і не використовувати виноску.
Павло

@Pavel І класичний, і ⎕ML←3застарілий, тому я б краще показав мову, як це було б зазвичай. Насправді майже всі мої рішення Dyalog APL вважають класичним лише тому, що ми рахуємо байти замість символів, хоча навіть версія Unicode призначає значення менше 256 символів.
Adám

1

PHP, 123 байти

for(;preg_match("#^(\S{".++$i."}.*
){"."$i}#",$s="$argv[1]
"););while($k<$i-1)echo substr(split("
",$s)[+$k++],0,$i-1),"
";

вимагає PHP 5.4, 5.5 або 5.6. Замінити splitз explodeдля подальшого PHP.

Запустіть php -nr '<code> '<string>'
або спробуйте в Інтернеті . (Переконайтесь, що ви вибрали відповідну версію PHP!)



1

Perl 5, 60 +5 (-0777p) байт

$.++while/^(.{$.}.*
){$.}/;$_=join"
",(/.{$.}/gm)[0..--$.-1]

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

  • Останній рядок введення повинен закінчуватися новим рядком, якщо він належить до виводу.
  • У разі двох послідовних нових рядків -00 варіант може бути змінений на -0777.

Можливі два наступні рядки, тому вам знадобиться -0777. Що робити -00і -0777робити, все одно.
Павло

-0полягає в тому, щоб вказати роздільник записів у восьмеричному форматі 777- це особливе значення для позначення відсутнього роздільника, тому весь файл читається, 0є ще одне спеціальне значення для позначення "абзацу в режимі", роздільник - більше 1 послідовних нових рядків
Nahuel Fouilleul

1

Perl 6 , 158 140 байт

my$c;for ^(my@b=lines).elems {any(@b.head(++$c).map({.substr(0,$c).chars <$c}))&&$c--&&last;};say @b.head($c).map({.substr(0,$c)}).join("
")

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

Ура за мою першу відповідь Perl 6. Я пограю з деякими параметрами командного рядка, щоб побачити, чи зможу я трохи більше пограти в гольф. Вся допомога в збереженні байтів вітається!


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