Ke atas dan ke depan untuk kemuliaan yang lebih besar!


15

Semoga tantangan ini berfungsi sebagai ( yang lain ) upeti kepada Stan Lee, yang meninggal berusia 95.

Stan Lee telah meninggalkan kami warisan yang tak ternilai dan kata tangkapan yang aneh: Excelsior . Jadi, inilah tantangan kecil berdasarkan apa yang dia katakan artinya :

Akhirnya, apa arti "Excelsior"? "Ke atas dan seterusnya untuk kemuliaan yang lebih besar!" Itulah yang saya harapkan setiap kali saya selesai tweeting! Excelsior!

Tantangan

Diberikan serangkaian bilangan bulat non-negatif, menghasilkan garis dengan Excelsior!setiap kali bilangan bulat lebih besar dari yang sebelumnya.

Aturan

  • Input akan berupa array bilangan bulat non-negatif.
  • Output akan terdiri dari baris-baris dengan kata Excelsior(case does matter) diikuti oleh sebanyak !panjangnya arus angka yang semakin besar. Anda juga dapat mengembalikan array string.
  • Format input dan output fleksibel sesuai dengan aturan situs, jadi silakan menyesuaikannya dengan format bahasa Anda. Anda juga dapat menambahkan spasi di akhir baris, atau bahkan menambahkan baris baru setelah atau sebelum teks jika Anda perlu.

Contohnya

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

Ini adalah , jadi semoga kode terpendek untuk setiap bahasa menang!


ouflak menganggap bilangan bulat adalah 1 digit, apakah itu ok
ASCII-only

1
@ ASCII-hanya tidak juga. Saya tidak tahu apakah LUA memiliki batasan dengan itu, tetapi jika itu tidak terjadi, ouflak harus mengurai bilangan bulat berapa pun panjangnya.
Charlie

@ Charlie Saya tidak tahu Lua, tetapi meskipun ini bertele-tele, dimungkinkan untuk mengambil contoh input yang dibatasi ruang dan dipisah seperti ini .
Kevin Cruijssen

Saya melihatnya. Caranya adalah untuk bisa menangani kedua skenario.
ouflak

Bahasa FWIW seperti C atau Javascript hanya akan menangani bilangan bulat dengan presisi (9/16 digit).
user202729

Jawaban:


9

JavaScript (ES6), 58 54 byte

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

Cobalah online!

Berkomentar

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

Mengapa menggunakan kembali [] untuk menyimpan nilai sebelumnya aman

Ada tiga kemungkinan kasus:

  • Jika a[ ] kosong, fungsi callback dari .map()tidak dipanggil sama sekali dan kami hanya mendapatkan array kosong, menghasilkan string kosong.
  • Jika a[ ] berisi tepat satu elemen x , itu dipaksa untuk elemen yang selama tes pertama (dan unik) a < (a = c). Jadi, kami menguji x<x , yang salah. Kami mendapatkan array yang berisi string kosong, menghasilkan lagi string kosong.
  • Jika a[ ] mengandung beberapa unsur, itu dipaksa untuk NaNselama tes pertama a < (a = c). Oleh karena itu, hasilnya palsu dan apa yang dieksekusi adalah inisialisasi s ke string kosong - yang merupakan apa yang kita inginkan. Perbandingan bermakna pertama terjadi pada iterasi ke-2.


5

05AB1E , 26 24 23 byte

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

-2 byte terima kasih kepada @ Kalpeb .

Cobalah secara online atau verifikasi semua kasus uji .

Penjelasan:

ü                        # 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

Lihat ini 05AB1E ujung tambang (bagian Cara string kompres bukan bagian dari kamus? ) Untuk memahami mengapa .•1Š¥èò²•adalah "excelsior".


2
Saya tidak benar-benar tahu 05AB1E tetapi tidak bisakah Anda bertukar 0Kgdengan O?
Kroppeb

@ Kalpeb Ah, benar-benar merindukan itu, tapi ya, saya memang bisa. Terima kasih! :)
Kevin Cruijssen

5

Perl 6 , 60 58 57 byte

-1 byte terima kasih kepada nwellnhof

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

Cobalah online!

Blok kode anonim yang mengembalikan daftar Excelsiors!


4

Java-8 118 113 Bytes

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");}

Mudah dibaca :

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");
    }
}

2
Berikut beberapa golfs untuk menyimpan 10 byte: 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+="!":"";}. Cobalah secara online ( 108 byte ). (Java 10+)
Kevin Cruijssen

@KevinCruijssen Terima kasih!
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 byte )
Olivier Grégoire

Memperbaiki masalah saya: ++ealih-alih e++agar setidaknya ada satu yang !akan dicetak.
Olivier Grégoire

1
@KevinCruijssen Kesalahan ketik kecil di golf Anda membuat Anda mendapatkan satu byte: e=...?e+"!":alih-alih e=...?e+="!":.
Olivier Grégoire

4

R , 86 byte

Setengah dari jawaban ini adalah @ Giuseppe. RIP Stan Lee.

function(a)for(i in diff(a))"if"(i>0,cat("Excelsior",rep("!",F<-F+1),"
",sep=""),F<-0)

Cobalah online!


4

05AB1E , 20 19 byte

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

Cobalah online!

Penjelasan

ü‹                    # 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"

4

C (gcc / dentang), 106 99 97 byte

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);}

Terimakasih untuk gastropner untuk bermain golf 2 byte.

Cobalah online sini .

Tidak Disatukan:

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

}

Saya mulai membuat solusi, tetapi akhirnya sangat dekat dengan Anda sehingga memposting milik saya sebagai jawaban terpisah terasa agak konyol. Namun, beberapa perbedaan yang ada dapat menghemat beberapa byte.
gastropner

@gastropner Terima kasih telah berbagi versi Anda. Saya telah memasukkan peningkatan Anda dan memutarnya lebih lanjut hingga 99 byte. Kalau saja kita tidak perlu menangani array kosong - jika tidak, itu akan menjadi 97 byte , menggunakan gaya loop Anda.
OOBalance

4

Japt -R, 25 22 byte

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

Cobalah

3 byte disimpan berkat Kamil

ò¨                      :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


The -RBendera tidak benar-benar diperlukan, tantangan mengatakan Anda dapat output array dari string.
Kamil Drakari

Bagus, terima kasih, @KamilDrakari. Saya mencoba menggunakan solusi slicepada pass pertama saya tetapi menolak ketika itu berhasil terlalu lama. Kembali ke sekarang, dengan bisikan Anda, saya kira saya harus terjebak dengan itu karena saya turun ke 22 juga.
Shaggy

3

Common Lisp, 111 byte

(setq i 0)(loop for(a b)on(read)do(incf i(if(and b(> b a))1(- i)))(format(> i 0)"Excelsior~v@{~a~:*~}~%"i #\!))

Cobalah online!


3

Java 8, 106 bytes

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;}

Try it online!

(those reassignments of s...yikes)


You can golf two more bytes by replacing (s="")+s => (s="")
O.O.Balance

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 bytes) Move the s="" to spare bytes.
Olivier Grégoire


3

R, 111 bytes

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

Try it online!

A far better R tribute can be found here -- I was too fixated on sequence and rle.


This doesn't give some blank lines, but 86 bytes?
J.Doe

2
@J.Doe dang, that's way better. I'd post that myself if I were you.
Giuseppe

3

Jelly, 16 bytes

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

A monadic Link yielding a list of lists of characters.

Try it online! (footer joins with newlines)

How?

<Ɲṣ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 bytes

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

Try it online!

Explanation, with simplified example:

ò¨                       :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 bytes

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

Less golfed test script:

$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
}

Output:

True
Excelsior!
True
Excelsior!
Excelsior!!
Excelsior!!!
Excelsior!!!!
True
True
True
Excelsior!
Excelsior!
Excelsior!!
Excelsior!
True
Excelsior!

1
There it is, I was trying to get a lag pointer to work but couldn't think of how.
Veskah

3

PowerShell, 87 85 bytes

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

Try it online!

There's probably a restructuring hiding in there, most likely in the if-else, but overall pretty alright. Uses the ol' "Un-instantiated variable defaults to 0" trick for both making the index and the !.


2

Retina, 55 bytes

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

Try it online! Link includes test cases. Explanation:

\d+
*

Convert to unary.

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

Process overlapping matches from right to left (although the matches are then listed from left to right). This means that we can match every number in a run, and the match extends to the start of the run. Each match is further constrained that each additional matched number must be less than the previously matched additional number, or the first number if no additional numbers have been matched yet.

L$...
Excelsior$#1*!

For each match, output Excelsior with the number of additional numbers in the run as desired.


2

Pyth, 32 bytes

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

Try it online here, or verify all the test cases at once here.

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


2

Lua, 88 87 83 82 96 95 113 bytes

Thanks @Kevin Cruijssen for update adhering to spirit of original question.

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

Try it online!


1
Sorry but you need to print the exclamation mark according to the rules (one exclamation mark per length of the current run of increasingly greater numbers).
Charlie

No problem. Think I've done as much as I can do here unless someone else sees something...
ouflak

1
I don't know Lua too well, but here is a fix for your code so it runs all test cases correctly Currently you just print an "!" more every time a number is higher than the previous, but you don't reset it back to 1 when that isn't the case. More can probably be golfed, but since I've never golfed in Lua I focused on fixing it with only minor golfs. PS: Not sure if assuming the input are always single digits is correct..
Kevin Cruijssen

2
Since @Charlie mentioned in a comment below the challenge description that it should be possible to take multi-digits numbers as input, here a possible fix by taking a space-delimited input and split on it.
Kevin Cruijssen

I decided that Kevin Cruijssen modifications are more inline with the OP's expectation. Thanks!
ouflak

2

C++ 14 (g++), 123 118 bytes

[](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;}

Fortunately std::string has a constructor that repeats a char. Try it online here.

Thanks to gastropner for saving 5 bytes.

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

}

You can shave off another 5 bytes
gastropner

2

C# (.NET Core), 115 107 105 bytes

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

Try it online!

-8 bytes: changed b to a string holding "!"s from an int counter
-2 bytes: set b+="!" as an inline function (thanks to Zac Faragher)

Uses an Action delegate to pull in the input and not require a return.

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
}

1
you can save 2 bytes by making the b+="!" inline with the Excelsior if(a[i]>a[i-1])Console.WriteLine("Excelsior"+(b+="!")); Try it online!
Zac Faragher

2

PHP, 117 109 bytes

<?php do{$i=next($argv);if($p!==null&&$p<$i){$e.='!';echo "
Excelsior$e";}else$e='';$p=$i;}while($i!==false);

Try it online!


2

J, 50 bytes

'Excelsior',"1'!'#"0~[:;@(([:<+/\);._1)0,2</\ ::0]

Try it online!

ungolfed

'Excelsior' ,"1 '!' #"0~ [: ;@(([: < +/\);._1) 0 , 2 </\ ::0 ]

1

Java, 113 bytes

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="";}}

1

VBA, 114 bytes

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

Unfortunately, this is not a valid solution as it relies on having an explicitly defined variable, a. That said, if you define the function as a subroutine that takes the input as a variant of expected type array, then you can turn your approach into a valid solution. A Golfed version of that approach would look like 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, where the breaks between code block represent new lines
Taylor Scott

1

Python 3, 87 bytes

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

Or 97 with the following:

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

This assumes inputs will be in the format:

32105
12345
<null input>
1
1213415
333343

1
Your first program is invalid as it takes input through a predefined variable. The second is invalud as it can't distinguish between numbers with multiple digits. Why not use Python 2 or turn it into a function instead?
Jo King

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.