Вверх и вперед к большей славе!

15

Пусть этот вызов послужит ( еще одной ) данью Стэну Ли, скончавшемуся в возрасте 95 лет.

Стэн Ли оставил нам неоценимое наследие и своеобразное ключевое слово: Эксельсиор . Итак, вот небольшая проблема, основанная на том, что он сказал, что это означало :

Наконец, что означает «Эксельсиор»? «Вверх и вперед, к великой славе!» Это то, чего я желаю вам, когда я заканчиваю твит! Excelsior!

Вызов

Учитывая последовательность неотрицательных целых чисел, выведите строку, Excelsior!каждый раз, когда целое число больше предыдущего.

правила

  • Входные данные будут массивом неотрицательных целых чисел.
  • Вывод будет состоять из строк со словом Excelsior(регистр имеет значение), за которым следует столько же, !сколько длина текущего прогона все больших чисел. Вы также можете вернуть массив строк.
  • Форматы ввода и вывода являются гибкими в соответствии с правилами сайта, поэтому не стесняйтесь адаптировать их к вашим языковым форматам. Вы также можете добавить пробелы в конце строк или даже дополнительные новые строки после или перед текстом, если вам нужно.

Примеры

Input             Output
-----------------------------------
[3,2,1,0,5]       Excelsior!      // Excelsior because 5 > 0

[1,2,3,4,5]       Excelsior!      // Excelsior because 2 > 1
                  Excelsior!!     // Excelsior because 3 > 2 (run length: 2)
                  Excelsior!!!    // Excelsior because 4 > 3 (run length: 3)
                  Excelsior!!!!   // Excelsior because 5 > 4 (run length: 4)

[]                <Nothing>

[42]              <Nothing>

[1,2,1,3,4,1,5]   Excelsior!      // Excelsior because 2 > 1
                  Excelsior!      // Excelsior because 3 > 1
                  Excelsior!!     // Excelsior because 4 > 3 (run length: 2)
                  Excelsior!      // Excelsior because 5 > 1

[3,3,3,3,4,3]     Excelsior!      // Excelsior because 4 > 3

Это , поэтому может выиграть самый короткий код для каждого языка!

Чарли
источник
ouflak предполагает, что целые числа имеют длину 1 цифра, это нормально
только для ASCII
1
@ ASCII-только не совсем. Я не знаю, имеет ли LUA ограничение с этим, но если это не так, ouflak должен анализировать целые числа любой длины.
Чарли
@Charlie Я не знаю Lua, но хотя он многословен, можно взять, например, разделенный пробелами ввод и разделить его следующим образом .
Кевин Круйссен
Я смотрю на это. Хитрость заключается в том, чтобы уметь обрабатывать оба сценария.
ouflak
Языки FWIW, такие как C или Javascript, в любом случае будут обрабатывать только целые числа с точностью до 9/16.
user202729

Ответы:

9

JavaScript (ES6), 58 54 байта

a=>a.map(c=>a<(a=c)?`Excelsior${s+='!'}
`:s='').join``

Попробуйте онлайн!

комментарии

a =>                           // a[] = input array, also used to store the previous value
  a.map(c =>                   // for each value c in a[]:
    a <                        //   compare the previous value
    (a = c)                    //   with the current one; update a to c
                               //   this test is always falsy on the 1st iteration
    ?                          //   if a is less than c:
      `Excelsior${s += '!'}\n` //     add a '!' to s and yield 'Excelsior' + s + linefeed
    :                          //   else:
      s = ''                   //     reset s to an empty string and yield an empty string
  ).join``                     // end of map(); join everything

Почему повторное использование [] для сохранения предыдущего значения безопасно

Есть три возможных случая:

  • Если [ ] пуст, то функция обратного вызова не вызывается на всех , и мы просто получаем пустой массив, получая пустую строку.a[ ].map()
  • Если a[ ] содержит ровно один элемент Икс , он приводится к этому элементу во время первого (и уникального) теста a < (a = c). Итак, мы тестируем Икс<Икс , что ложно. Мы получаем массив, содержащий пустую строку, снова получая пустую строку.
  • Если a[ ] содержит несколько элементов, оно применяется NaNво время первого теста a < (a = c). Следовательно, результат ложный, и выполняется инициализация s пустой строкой - что мы и хотим. Первое значимое сравнение происходит на 2-й итерации.
Arnauld
источник
5

Python 2 , 84 83 81 70 68 байт

a=n=''
for b in input():
 n+='!';n*=a<b;a=b
 if n:print'Excelsior'+n

Попробуйте онлайн!

-2 байта, только благодаря ASCII

TFeld
источник
68?
Только для ASCII
@ Только для ASCII Спасибо :)
TFeld
функции слишком длинные :(
ASCII-only
ну, по крайней мере, рекурсивные подходы
только ASCII
5

05AB1E , 26 24 23 байта

ü‹γvyOE.•1Š¥èò²•™N'!׫,

-2 байта благодаря @Kroppeb .

Попробуйте онлайн или проверьте все контрольные примеры .

Объяснение:

ü                        # Loop over the (implicit) input as pairs
                        #  And check for each pair [a,b] if a<b is truthy
                         #   i.e. [1,2,1,3,4,1,5,7,20,25,3,17]
                         #   → [1,0,1,1,0,1,1,1,1,0,1]
  γ                      # Split it into chunks of equal elements
                         #  i.e. [1,0,1,1,0,1,1,1,1,0,1]
                         #   → [[1],[0],[1,1],[0],[1,1,1,1],[0],[1]]
   vy                    # Foreach `y` over them
     O                   #  Take the sum of that inner list
                         #   i.e. [1,1,1,1] → 4
                         #   i.e. [0] → 0
      E                  #  Inner loop `N` in the range [1, length]:
       .•1Š¥èò²•         #   Push string "excelsior"
                        #   Titlecase it: "Excelsior"
                 N'!׫  '#   Append `N` amount of "!"
                         #    i.e. N=3 → "Excelsior!!!"
                      ,  #   Output with a trailing newline

Посмотрите эту подсказку 05AB1E (раздел Как сжимать строки, не являющуюся частью словаря? ), Чтобы понять, почему .•1Š¥èò²•это так "excelsior".

Кевин Круйссен
источник
2
Я действительно не знаю 05AB1E, но вы не можете обменять 0Kgс O?
Кроппеб
@Kroppeb Ах, совсем не хватало этого, но да, я действительно могу. Благодарность! :)
Кевин Круйссен
5

Perl 6 , 60 58 57 байт

-1 байт благодаря nwellnhof

{"Excelsior"X~("!"Xx grep +*,[\[&(-+^*×*)]] .skip Z>$_)}

Попробуйте онлайн!

Блок анонимного кода, который возвращает список Excelsiors!

Джо Кинг
источник
4

Java-8 118 113 байт

n->{String e="";for(int i=0;i<n.length-1;)System.out.print(""==(n[i+1]>n[i++]?e+="!":(e=""))?e:"Excelsior"+e+"\n");}

Легко читать:

private static void lee(int num[]) {
    String exclamation = "";
    for (int i = 0; i < num.length - 1;) {
        exclamation = num[i + 1] > num[i++] ? exclamation += "!" : "";
        System.out.print("".equals(exclamation) ? "" : "Excelsior" + exclamation + "\n");
    }
}
CoderCroc
источник
2
Вот некоторые гольфы , чтобы сохранить 10 байт: n->{var e="";for(int i=0;i<n.length-1;System.out.print(""==e?e:"Excelsior"+e+"\n"))e=n[i++]<n[i]?e+="!":"";}. Попробуйте онлайн ( 108 байт ). (Java 10+)
Кевин Круйссен
@KevinCruijssen Спасибо!
CoderCroc
2
n->{for(int e=0,i=0;i<n.length-1;)if(n[i++]<n[i])System.out.println("Excelsior"+"!".repeat(e++));else e=0;}( 107 байт )
Оливье Грегуар,
Исправление моей проблемы: ++eвместо того, e++чтобы был хотя бы один !для печати.
Оливье Грегуар
1
@KevinCruijssen Маленькая опечатка в вашем гольфе, чтобы вы получили один байт: e=...?e+"!":вместо e=...?e+="!":.
Оливье Грегуар
4

05AB1E , 20 19 байтов

ü‹0¡€ƶ˜ε'!×”¸Îsiorÿ

Попробуйте онлайн!

объяснение

ü‹                    # pair-wise comparison, less-than
  0¡                  # split at zeroes
    €ƶ                # lift each, multiplying by its 1-based index
      ˜               # flatten
       ε              # apply to each
        '!×           # repeat "!" that many times
                  ÿ   # and interpolate it at the end of
           ”¸Îsior    # the compressed word "Excel" followed by the string "sior"
Emigna
источник
4

C (gcc / clang), 106 99 97 байт

f(a,n)int*a;{int r=0,s[n];for(memset(s,33,n);n-->1;)r*=*a<*++a&&printf("Excelsior%.*s\n",++r,s);}

Спасибо гастропнеру за игру в гольф 2 байта.

Попробуйте это онлайн здесь .

Ungolfed:

f(a, n) // function taking a pointer to the first integer and the length of the array
  int *a; { // a is of type pointer to int, n is of type int

    int r = 0, // length of the current run
        i = 0, // loop variable
        s[n];  // buffer for exclamation marks; we will never need more than n-1 of those (we are declaring an array of int, but really we will treat it as an array of char)

    for(memset(s, 33, n); // fill the buffer with n exclamation marks (ASCII code 33)
        n -- > 1; ) // loop over the array

        r *= *a < *(++ a) // if the current element is less than the next:
             && printf("Excelsior%.*s\n", // print (on their own line) "Excelsior", followed by ...
                       ++ r, // ... r (incremented) of the ...
                       s) // ... n exclamation marks in the buffer s
             ; // else r is reset to 0

}
OOBalance
источник
Я начал принимать решение, но в итоге оказался настолько близок к вашему, что публикация моего ответа в качестве отдельного ответа показалась мне немного глупой. Тем не менее, некоторые отличия могут сэкономить вам несколько байтов.
гастропнер
@gastropner Спасибо, что поделились своей версией. Я включил ваши улучшения и увеличил его до 99 байтов. Если бы только нам не нужно было обрабатывать пустой массив - иначе это было бы 97 байтов , используя ваш стиль цикла.
OOBalance
4

Japt -R, 25 22 байта

ò¨ ËÅ£`Ex­lÐâ`ú'!Y+A
c

Попытайся

3 байта сохранены благодаря Камилу

ò¨                      :Partition at items that are greater than or equal to the previous item
   Ë                    :Map
    Å                   :  Slice off the first element
     £                  :  Map each element at 0-based index Y
      `Ex­lÐâ`           :    Compressed string "Excelsior"
             ú'!        :    Right pad with exclamation marks
                Y+A     :     To length Y+10
c                       :Flatten
                        :Implicitly join with newlines & output
мохнатый
источник
Еще 25 байтов
Луис Фелипе Де Хесус Муньос
-RФлаг на самом деле не нужно, задача говорит , что вы можете вывести массив строк.
Камил Дракари
Хороший, спасибо, @KamilDrakari. Я попробовал решение, используя sliceмой первый проход, но отклонил его, когда оно получилось слишком долго. Возвращаясь к этому сейчас, с вашей подсказкой, я полагаю, я должен был придерживаться этого, потому что я тоже снизил до 22.
Лохматый
3

Java 8, 106 байт

n->{String s="",z=s;for(int i=0;i<n.length-1;)z+=n[i++]<n[i]?"Excelsior"+(s+="!")+"\n":(s="")+s;return z;}

Попробуйте онлайн!

(эти переназначения s... yikes)

NotBaal
источник
Вы можете (s="")+s(s="")
сыграть в
1
n->{String s="",z=s;for(int i=0;i<n.length-1;)z+=n[i++]>=n[i]?s="":"Excelsior"+(s+="!")+"\n";return z;}( 103 байта ) Переместить в s=""запасные байты.
Оливье Грегуар
3

R 111 байтов

function(a,r=rle(sign(diff(a))),v=r$l[r$v>0])write(paste0(rep("Excelsior",sum(v)),strrep("!",sequence(v))),1,1)

Попробуйте онлайн!

Гораздо лучше R дань можно найти здесь - я был слишком зациклен на sequenceи rle.

Giuseppe
источник
Это не дает несколько пустых строк, но 86 байтов?
J.Doe
2
@ J.До черт, лучше. Я бы опубликовал это сам на твоем месте.
Джузеппе
3

Желе , 16 байт

<Ɲṣ0ÄẎ”!ẋ“Ø6ḥ»;Ɱ

Монадическая ссылка, выдающая список списков символов.

Попробуйте онлайн!(нижний колонтитул соединяется с новыми строками)

Как?

<Ɲṣ0ÄẎ”!ẋ“Ø6ḥ»;Ɱ - Link: list of integers     e.g. [1,1,4,2,1,1,3,4]
 Ɲ               - for each pair of integers:      [1,1] [1,4] [4,2] [2,1] [1,1] [1,3] [3,4]
<                -   less than?                    [  0,    1,    0,    0,    0,    1,    1]
  ṣ0             - split at zeros                  [[],    [1],     [],   [],      [1,    1]]
    Ä            - cumulative sums                 [[],    [1],     [],   [],      [1,    2]]
     Ẏ           - tighten                         [1,1,2]
      ”!         - literal '!' character           '!'
        ẋ        - repeat (vectorises)             [['!'],['!'],['!','!']]
         “Ø6ḥ»   - dictionary lookup               ['E','x','c','e','l','s','i','o','r']
               Ɱ - map with:
              ;  -   concatenate                   [['E','x','c','e','l','s','i','o','r','!'],['E','x','c','e','l','s','i','o','r','!'],['E','x','c','e','l','s','i','o','r','!','!']]
Джонатан Аллан
источник
3

Japt , 22 байта

ò¨ ®£`Ex­lÐâ`+'!pYÃÅÃc

Попробуйте онлайн!

Пояснение с упрощенным примером:

ò¨                       :Split whenever the sequence does not increase
                           e.g. [2,1,1,3] -> [[2],[1],[1,3]]
   ®               Ã     :For each sub-array:
    £            Ã       :  For each item in that sub-array:
     `Ex­lÐâ`             :    Compressed "Excelsior"
            +            :    Concat with
             '!pY        :    a number of "!" equal to the index
                               e.g. [1,3] -> ["Excelsior","Excelsior!"]
                  Å      :  Remove the first item of each sub-array
                            e.g. [[Excelsior],[Excelsior],[Excelsior,Excelsior!]]->[[],[],[Excelsior!]]
                    c    :Flatten
                           e.g. [[],[],[Excelsior!]] -> [Excelsior!]
Камил Дракари
источник
3

Powershell, 69 байт

$args|%{if($o-ne$e-and$_-gt$o){'Excelsior'+'!'*++$c}else{$c=0}$o=$_}

Менее гольф тестовый скрипт:

$f = {

$args|%{
    if($old-ne$empty-and$_-gt$old){
        'Excelsior'+'!'*++$c
    }else{
        $c=0
    }
    $old=$_
}

}

@(
    ,( (3,2,1,0,5),  'Excelsior!')      # Excelsior because 5 > 0

    ,( (1,2,3,4,5),  'Excelsior!',      # Excelsior because 2 > 1
                    'Excelsior!!',     # Excelsior because 3 > 2 (run length: 2)
                    'Excelsior!!!',    # Excelsior because 4 > 3 (run length: 3)
                    'Excelsior!!!!')   # Excelsior because 5 > 4 (run length: 4)

    ,( $null,         '')                # <Nothing>

    ,( (42),          '')                # <Nothing>

    ,( (1,2,1,3,4,1,5), 'Excelsior!',      # Excelsior because 2 > 1
                        'Excelsior!',      # Excelsior because 3 > 1
                        'Excelsior!!',     # Excelsior because 4 > 3 (run length: 2)
                        'Excelsior!')      # Excelsior because 5 > 1

    ,( (3,3,3,3,4,3),   'Excelsior!')      # Excelsior because 4 > 3
) | % {
    $a,$expected = $_
    $result = &$f @a
    "$result"-eq"$expected"
    $result
}

Выход:

True
Excelsior!
True
Excelsior!
Excelsior!!
Excelsior!!!
Excelsior!!!!
True
True
True
Excelsior!
Excelsior!
Excelsior!!
Excelsior!
True
Excelsior!
Mazzy
источник
1
Я пытался заставить указатель задержки работать, но не мог придумать, как это сделать.
Веска
3

PowerShell , 87 85 байт

param($n)for(;++$i-lt$n.count){if($n[$i]-gt$n[$i-1]){"Excelsior"+"!"*++$c}else{$c=0}}

Попробуйте онлайн!

Вероятно, там прячется реструктуризация, скорее всего, в случае если-либо, но в целом все в порядке. Использует трюк "Неинстанцированная переменная по умолчанию 0" для создания индекса и !.

Veskah
источник
2

Сетчатка , 55 байт

\d+
*
L$rv`(_*,(?<!(?(1)\1|\2,)))+(_+)\b
Excelsior$#1*!

Попробуйте онлайн! Ссылка включает в себя тестовые случаи. Объяснение:

\d+
*

Преобразовать в одинарный.

rv`(_*,(?<!(?(1)\1|\2,)))+(_+)\b

Обрабатывать перекрывающиеся совпадения справа налево (хотя совпадения затем отображаются слева направо). Это означает, что мы можем сопоставить каждое число в серии, и совпадение распространяется на начало цикла. Каждое совпадение дополнительно ограничено тем, что каждое дополнительное совпадающее число должно быть меньше, чем ранее сопоставленное дополнительное число, или первое число, если дополнительные числа еще не сопоставлены.

L$...
Excelsior$#1*!

Для каждого совпадения выведите Excelsiorколичество дополнительных чисел в прогоне по желанию.

Нил
источник
2

Pyth, 32 байта

j+L"Excelsior"*L\!fT.u*hN<0Y.+Q0

Попробуйте онлайн здесь или проверьте все тестовые примеры сразу здесь .

j+L"Excelsior"*L\!fT.u*hN<0Y.+Q0   Implicit: Q=eval(input())
                            .+Q    Get forward difference between consecutive elements of Q
                    .u         0   Reduce the above, returning all steps, with current value N starting at 0, next element as Y, using:
                       hN            N+1
                      *              Multiplied by
                         <0Y         1 if 0<Y, 0 otherwise
                  fT               Filter to remove 0s
              *L\!                 Repeat "!" each element number of times
 +L"Excelsior"                     Prepend "Excelsior" to each
j                                  Join on newlines, implicit print
Sok
источник
2

Луа , 88 87 83 82 96 95 113 байтов

Спасибо @Kevin Cruijssen за обновление, придерживающееся духа оригинального вопроса.

s=io.read()n=9 e="Excelsior!"f=e
for c in s.gmatch(s,"%S+")do if n<c+0then print(e)e=e..'!'else e=f end n=c+0 end

Попробуйте онлайн!

ouflak
источник
1
Извините, но вам нужно напечатать восклицательный знак в соответствии с правилами (один восклицательный знак на длину текущего прогона все больших чисел).
Чарли
Нет проблем. Думаю, я сделал столько, сколько смогу, если кто-то еще не увидит что-то ...
ouflak
1
Я не очень хорошо знаю Lua, но здесь есть исправление для вашего кода, поэтому он правильно выполняет все тестовые сценарии. В настоящее время вы просто печатаете "!" больше каждый раз, когда число выше предыдущего, но вы не сбрасываете его обратно на 1, если это не так. Возможно, еще можно играть в гольф, но так как я никогда не играл в гольф в Луа, я сосредоточился на том, чтобы починить его только с небольшими полями для гольфа. PS: Не уверен, если предположить, что ввод всегда состоит из одной цифры правильно ..
Кевин Круйссен
2
Поскольку @Charlie упомянул в комментарии ниже описание вызова, что должна быть возможность принимать многозначные числа в качестве входных данных, здесь возможное исправление, приняв ввод с разделителями пробелом и разделив его .
Кевин Круйссен
Я решил, что модификации Кевина Круйссена более соответствуют ожиданиям ОП. Благодарность!
ouflak
2

C ++ 14 (g ++), 123 118 байт

[](auto a){for(int n=0,i=0;++i<a.size();)a[i]>a[i-1]?puts(&("Excelsior"+std::string(++n,33))[0]):n=0;}

К счастью, std::stringесть конструктор, который повторяет char. Попробуйте онлайн здесь .

Спасибо гастропнеру за сохранение 5 байтов.

Ungolfed:

[] (auto a) { // void lambda taking a std::array of integer

    for(int n = 0, // length of the current run
        i = 0; // loop variable
        ++ i < a.size(); ) // start with the second element and loop to the last
        a[i] > a[i - 1] // if the current element is greater than the previous ...
        ? puts( // ... print a new line:
               &("Excelsior" + // "Excelsior, followed by ...
                std::string(++ n, 33)) // ... the appropriate number of exclamation marks (33 is ASCII code for '!'); increment the run length
               [0]) // puts() takes a C string
        : n = 0; // else reset run length

}
OOBalance
источник
Вы можете сбрить еще 5 байтов
gastropner
2

C # (.NET Core) , 115 107 105 байтов

a=>{var b="";for(int i=0;++i<a.Length;)if(a[i]>a[i-1])Console.WriteLine("Excelsior"+(b+="!"));else b="";}

Попробуйте онлайн!

-8 байт: изменено b на строку, содержащую "!" Из счетчика int
-2 байта: установлено b+="!" как встроенная функция (спасибо Заку Фарагеру )

Использует делегат Action для ввода данных и не требует возврата.

Ungolfed:

a => {
    var b = "";                         // initialize the '!' string (b)
    for(int i = 0; ++i < a.Length;)     // from index 1 until the end of a
        if(a[i] > a[i - 1])                 // if the current index is greater than the previous index
            Console.WriteLine("Excelsior" +     // on a new line, print "Excelsior"
                                    (b += "!"));    // add a "!" to b, and print the string
        else                                // if the current index is not greater than the previous index
            b = "";                             // reset b
}
Meerkat
источник
1
Вы можете сэкономить 2 байта, сделав b+="!"строку встроенной в Excelsior. if(a[i]>a[i-1])Console.WriteLine("Excelsior"+(b+="!")); Попробуйте онлайн!
Зак Фарагер
1

Java, 113 байт

String i="";for(int a=0;a<s.length-1;a++){if(s[a+1]>s[a]){i+="!";System.out.println("Excelsior"+i);}else{i="";}}
isaace
источник
1

VBA, 114 байт

For i=0 To UBound(a)-LBound(a)-1 If a(i+1)>a(i)Then s=s&"!" Debug.Print("Excelsior"&s&"") Else s="" End If Next i
isaace
источник
К сожалению, это неверное решение, поскольку оно основано на наличии явно определенной переменной a. Тем не менее, если вы определите функцию как функцию, subroutineкоторая принимает входные данные как вариант массива ожидаемого типа, то вы можете превратить свой подход в правильное решение. Гольф-версия этого подхода будет выглядеть так sub f(x) For i=0To UBound(x)-1 If x(i+1)>x(i)Then s=s+"!":Debug.?"Excelsior"s:Else s="" Next End Sub, где разрывы между блоками кода представляют новые строки
Тейлор Скотт
1

Python 3, 87 байт

c='!'
for i in range(1,len(n)):
    if n[i]>n[i-1]:print('Excelsior'+c);c+='!'
    else:c='!'

Или 97 со следующим:

c='!';n=input()
for i in range(1,len(n)):
    if n[i]>n[i-1]:print('Excelsior'+c);c+='!'
    else:c='!'

Это предполагает, что входные данные будут в формате:

32105
12345
<null input>
1
1213415
333343
Генри Т
источник
1
Ваша первая программа недействительна, так как она принимает ввод через предопределенную переменную. Второй - это недействительность, поскольку он не может различить числа с несколькими цифрами. Почему бы не использовать Python 2 или превратить его в функцию ?
Джо Кинг,