29
\$\begingroup\$

Given a list of integers, your task is to output the second largest value in the first k elements, for each k between 2 and the length of the input list.

In other words, output the second largest value for each prefix of the input.

You can output an arbitrary value for the first element (where k = 1), or simply omit this value, as there isn't a second maximum for a list of 1 element. You may assume there are at least 2 elements in the input.

Shortest code wins.

Examples

Input:
1 5 2 3 5 9 5 8
Output:
  1 2 3 5 5 5 8
Input:
1 1 2 2 3 3 4
Output:
  1 1 2 2 3 3
Input:
2 1 0 -1 0 1 2
Output:
  1 1 1 1 1 2
\$\endgroup\$
11
  • \$\begingroup\$ My English isn't the best, how is k determined? \$\endgroup\$
    – LiefdeWen
    Aug 11, 2017 at 12:17
  • \$\begingroup\$ @LiefdeWen Output a list containing the answer for each k. \$\endgroup\$
    – jimmy23013
    Aug 11, 2017 at 12:24
  • 3
    \$\begingroup\$ 1 is not, strictly speaking, the second largest value of 1,1 (2nd example) it's the second value when sorted descending. \$\endgroup\$ Aug 11, 2017 at 12:49
  • \$\begingroup\$ Maybe I'm just stupid (although I suspect I could really have the weekend started..), but I'm still not sure how this works. Could someone ELI5 the last test case to me? The first two test cases I can solve by just looping over the list, determining the current minimum of the list, and then remove that item (or easier: sort list and remove last item). It gives the correct results for the first two test cases, but is obviously wrong (and will give -1, 0, 0, 1, 1, 2 for the last test case.) \$\endgroup\$ Aug 11, 2017 at 14:32
  • 1
    \$\begingroup\$ @KevinCruijssen Remember the two largest numbers you have seen. In the last case, you start with 2 being the largest, and output nothing/whatever since it doesn't make sense at this point. Then you change to 1 and 2 at the next iteration, so you output 1. This stays the same until you reach the 2 at the end, and then you have 2 and 2 as the largest and second largest \$\endgroup\$ Aug 11, 2017 at 14:36

37 Answers 37

6
\$\begingroup\$

05AB1E, 5 bytes

ηεà\à

Try it online!

Returns [] (arbitrary value) for first.

\$\endgroup\$
4
  • \$\begingroup\$ η¦ε{¨θ should work for 6 bytes \$\endgroup\$
    – Adnan
    Aug 11, 2017 at 12:33
  • \$\begingroup\$ @Adnan Of course >_< found a better way anyways though... \$\endgroup\$ Aug 11, 2017 at 12:33
  • \$\begingroup\$ Interesting... Z©KZ®‚¹sà was what I was thinkinh, didn't know à was even a thing! \$\endgroup\$ Aug 11, 2017 at 13:54
  • \$\begingroup\$ Found another 5-byte alternative. I used Áθ instead. \$\endgroup\$
    – Mr. Xcoder
    Aug 11, 2017 at 14:02
6
\$\begingroup\$

Husk, 9 7 bytes

Saved a byte or two thanks to @Zgarb

mȯ→hOtḣ

Returns 0 for the first "second maximum"

Explaination

         -- implicit input, e.g          [1,5,3,6]
      ḣ  -- prefixes                     [[],[1],[1,5],[1,5,3],[1,5,3,6]]
     t   -- remove the first element     [[1],[1,5],[1,5,3],[1,5,3,6]]
mȯ       -- map the composition of 3 functions
    O    --   sort                       [[1],[1,5],[1,3,5],[1,3,5,6]]
   h     --   drop the last element      [[],[1],[1,3],[1,3,5]
  →      --   return the last element    [0,1,3,5]
         -- implicit output

Try it online!

\$\endgroup\$
2
  • 1
    \$\begingroup\$ You could map →hO instead and save a byte. \$\endgroup\$
    – Zgarb
    Aug 11, 2017 at 13:16
  • \$\begingroup\$ I suppose that the Husk command "" (prefixes) must have subtly changed since this was originally posted, as this answer seems to work with only 6 bytes now... \$\endgroup\$ Jan 30, 2021 at 22:50
4
\$\begingroup\$

Python 2, 54 bytes

lambda x:[sorted(x[:i])[-2]for i in range(2,1+len(x))]

Try it online!

\$\endgroup\$
4
\$\begingroup\$

Nekomata, 4 bytes

poil

Attempt This Online!

p     Prefix
 o    Sort
  i   Init (remove the last element)
   l  Last

Accidentally, poil means hair in French.

\$\endgroup\$
1
  • 1
    \$\begingroup\$ I've been waiting so long for one of these golf langs to spell an actual word! \$\endgroup\$
    – chunes
    Mar 23 at 3:06
3
\$\begingroup\$

JavaScript (ES6), 58 51 50 bytes

Saved 1 byte thanks to @Neil

Appends undefined for k = 1.

a=>a.map(e=>(b=[e,...b]).sort((a,b)=>b-a)[1],b=[])

Test cases

NB: This snippet uses JSON.stringify() for readability, which -- as a side effect -- converts undefined to null.

let f =

a=>a.map(e=>(b=[e,...b]).sort((a,b)=>b-a)[1],b=[])

console.log(JSON.stringify(f([1, 5, 2, 3, 5, 9, 5, 8]))) // 1 2 3 5 5 5 8
console.log(JSON.stringify(f([1, 1, 2, 2, 3, 3, 4])))    // 1 1 2 2 3 3
console.log(JSON.stringify(f([2, 1, 0, -1, 0, 1, 2])))   // 1 1 1 1 1 2

\$\endgroup\$
2
  • 1
    \$\begingroup\$ I think a=>a.map(e=>(b=[e,...b]).sort((a,b)=>b-a)[1],b=[]) is only 50. \$\endgroup\$
    – Neil
    Aug 11, 2017 at 12:57
  • \$\begingroup\$ @Neil Nice. :-) \$\endgroup\$
    – Arnauld
    Aug 11, 2017 at 13:14
3
\$\begingroup\$

Python 2, 45 bytes

f=lambda l:l[1:]and f(l[:-1])+[sorted(l)[-2]]

Try it online!

The right side of the code is self-explanatory. However, what do we put to the left of the and? Because we are concatenating parts of a list recursively, we need the left side to be truthy if l has 2 or more elements, and an empty list otherwise. l[1:] satisfies this criterion nicely.

\$\endgroup\$
2
\$\begingroup\$

Pyth, 8 bytes

m@Sd_2._

Try it online! or Try the Test Suite!


How?

This outputs the first element of the list as the first value in the list, as per the spec You can output an arbitrary value for the first element.

m@Sd_2._   - Full program with implicit input.

m     ._Q  - Map over the prefixes of the input with a variable d.
  Sd       - Sorts the current prefix.
 @         - Gets the element...
    _2       - At index - 2 (the second highest).
           - Print implicitly.
\$\endgroup\$
0
2
\$\begingroup\$

Jelly, 8 bytes

ḣJṢ€Ṗ€Ṫ€

Try it online!

The first value will be 0, always, and the following numbers will be the second maximums of each prefix.

Explanation

ḣJṢ€Ṗ€Ṫ€  Input: array A
 J        Enumerate indices, [1, 2, ..., len(A)]
ḣ         Head, get that many values from the start for each, forms the prefixes
  Ṣ€      Sort each
    Ṗ€    Pop each, removes the maximum
      Ṫ€  Tail each
\$\endgroup\$
3
  • \$\begingroup\$ @Challenger5 I don't believe that works \$\endgroup\$
    – miles
    Aug 13, 2017 at 17:14
  • \$\begingroup\$ @Challenger5 That doesn't work... \$\endgroup\$ Aug 13, 2017 at 19:53
  • \$\begingroup\$ @EriktheOutgolfer Oh, ok. \$\endgroup\$ Aug 14, 2017 at 16:25
2
\$\begingroup\$

Java (OpenJDK 8), 87 86 bytes

a->{int x,y=x=1<<-1;for(int c:a){if((c>x?x=c:c)>y){x=y;y=c;}System.out.print(x+" ");}}

Try it online!

\$\endgroup\$
1
  • \$\begingroup\$ +1 for int x,y=x=. I didn't know separate declaration and assignment could be done in the same statement. \$\endgroup\$
    – Jakob
    Aug 11, 2017 at 22:00
2
\$\begingroup\$

J, 13 bytes

_2&{@/:~ ::#\

Try it online! The first element is always 1.

Explanation

_2&{@/:~ ::#\
            \  Apply to prefixes
_2&{@/:~        Sort and take second-to-last atom
     /:~         Sort upwards
_2 {             Take second-to-last atom
         ::     If there's an error (i.e only one atom)
           #     Return the length of the list (1)

The space matters.

\$\endgroup\$
2
\$\begingroup\$

Jelly, 5 bytes

Ṣ-ịƊƤ

Try it online!

Outputs the first value of the input as the first value in the output. This can be removed for adding one byte.

How it works

Ṣ-ịƊƤ - Main link. Takes l on the left
    Ƥ - Generate the prefixes of l
   Ɗ  - Run the following code over each prefix:
Ṣ     -   Sort the prefix
 -ị   -   Take the -1th index.
      -     Jelly lists are 1 indexed and modular. This means that the 0th index of a list is the final element and -1 the second to last element
\$\endgroup\$
2
\$\begingroup\$

Scala, 58 46 bytes

x=>2 to x.size map(x take _ sortBy(-_)apply 1)

Try it online!

Takes a List as an argument, and returns a Vector.

-12 bytes from user.

\$\endgroup\$
1
  • \$\begingroup\$ Make that 46 bytes by sorting in reverse, actually. \$\endgroup\$
    – user
    Jan 29, 2021 at 18:02
2
\$\begingroup\$

Zsh, 32 bytes

for x;a+=($x)&&<<<${${(On)a}[2]}

Try it online!

Reverse Order numerically, <<< print the [2]nd element.

\$\endgroup\$
2
\$\begingroup\$

Desmos, 44 bytes

f(x)=[x[1...i].sort[i-1]fori=[2...x.length]]

Try it on Desmos!

\$\endgroup\$
2
\$\begingroup\$

Thunno 2, 5 bytes

ƒıṠṫt

Try it online!

Uses [] as the (arbitrary) first value.

Explanation

ƒıṠṫt  # Implicit input
ƒ      # Prefixes of the input
 ı     # Map over this list:
  Ṡ    #  Sort this list
   ṫt  #  Second-last item
       # Implicit output
\$\endgroup\$
1
\$\begingroup\$

C# (Mono), 81 bytes

using System.Linq;a=>a.Select((_,i)=>a.Take(++i).OrderBy(n=>n).Skip(i-2).First())

Try it online!

\$\endgroup\$
1
\$\begingroup\$

Brachylog, 10 bytes

a₀ᶠb{okt}ᵐ

Try it online!

\$\endgroup\$
1
\$\begingroup\$

Batch, 123 bytes

@set/af=s=%1
@for %%n in (%*)do @call:c %%n
@exit/b
:c
@if %1 gtr %s% set s=%1
@if %1 gtr %f% set/as=f,f=%1
@echo %s%
\$\endgroup\$
1
\$\begingroup\$

APL (Dyalog), 15 bytes

(2⊃⍒⊃¨⊂)¨1↓,\∘⊢

Try it online!

\$\endgroup\$
1
\$\begingroup\$

05AB1E, 5 bytes

Found another 5-byter, very different from Erik's solution. The arbitrary value is the first element of the list.

ηε{Áθ

Try it online!


Explanation

ηε{Áθ  - Full program that reads implicitly from STDIN and outputs to STDOUT.

η      - Push the Prefixes of the list.
 ε     - Apply to each element (each prefix):
  {      - Sort the prefix list.
   Á     - Shift the list to the right by 1, such that the first element goes to the 
           beginning  and the second largest one becomes the last.
    θ    - Get the last element (i.e. the second largest)
         - Print implicitly.

Let's take an example, to make it easier to understand.

  • First we get the implicit input, let's say it's [1, 5, 2, 3, 5, 9, 5, 8].

  • Then, we push its prefixes using η - [[1], [1, 5], [1, 5, 2], [1, 5, 2, 3], [1, 5, 2, 3, 5], [1, 5, 2, 3, 5, 9], [1, 5, 2, 3, 5, 9, 5], [1, 5, 2, 3, 5, 9, 5, 8]].

  • Now, the code maps through the list and sorts each prefix using { - [[1], [1, 5], [1, 2, 5], [1, 2, 3, 5], [1, 2, 3, 5, 5], [1, 2, 3, 5, 5, 9], [1, 2, 3, 5, 5, 5, 9], [1, 2, 3, 5, 5, 5, 8, 9]].

  • We then take the very last element and move it to the beginning: [[1], [5, 1], [5, 1, 2], [5, 1, 2, 3], [5, 1, 2, 3, 5], [9, 1, 2, 3, 5, 5], [9, 1, 2, 3, 5, 5, 5], [9, 1, 2, 3, 5, 5, 5, 8]].

  • Of course, now the code gets the last element of each sublist using θ - [1, 1, 2, 3, 5, 5, 5, 8] (the first one being the arbitrary value.

\$\endgroup\$
1
\$\begingroup\$

CJam, 16 bytes

{_,,:)\f{<$-2=}}

Try it online!

Returns first element for first.

-2 thanks to Challenger5.

\$\endgroup\$
1
  • \$\begingroup\$ {_,,:)\f{<$-2=}} is two bytes shorter. \$\endgroup\$ Aug 11, 2017 at 17:25
1
\$\begingroup\$

R, 54 49 bytes

Thanks to Giuseppe -5 bytes. I did not know this feature of seq().

for(i in seq(x<-scan()))cat(sort(x[1:i],T)[2],"")

Try it online!

\$\endgroup\$
1
  • 1
    \$\begingroup\$ seq(x<-scan()) is shorter by a few bytes. \$\endgroup\$
    – Giuseppe
    Aug 11, 2017 at 17:43
1
\$\begingroup\$

Japt, 12 10 bytes

The output array consists of the first element in the input array followed by the desired sequence.

£¯YÄ n< g1

Test it


Explanation

Implicit input of array U.

£

Map over U, where Y is the current index.

¯YÄ

Slice U from 0 to Y+1.

n<

Sort descending.

g1

Get the second element.

Implicitly output the resulting array.

\$\endgroup\$
1
\$\begingroup\$

MATL, 19 10 bytes

Thanks to Luis Mendo for shaving off 9 bytes!

"GX@:)SP2)

Try it here.

Explanation

"GX@:)SP2)
"                  for all the values in the input
 G                 get input
  X@:)             get values up to the iteration
      SP           sort it in descending order
        2)         get the second value
                   implicit end of loop and output
\$\endgroup\$
1
  • \$\begingroup\$ @LuisMendo Wow! Goes to show how much I know about MATL. Thanks for the help! \$\endgroup\$
    – DanTheMan
    Aug 12, 2017 at 19:35
1
\$\begingroup\$

k, 13 bytes

{x(>x)1}'1_,\

Try it online!

           ,\ /sublists of increasing lengths (scan concat)
         1_   /remove the first sublist
{      }'     /for each sublist:
  (>x)        /    indices to permute sublist into largest to smallest
      1       /    get second index
 x            /    get sublist[that index]
\$\endgroup\$
1
\$\begingroup\$

Ohm, 10 8 bytes

-2 bytes thanks to ETHproductions.

∙p»îS2~ª

Try it online!

Uh, this is odd but I don't know how else to push a negative number... I don't really know Ohm. :P

\$\endgroup\$
3
  • 1
    \$\begingroup\$ Okay, 0 2- seems very strange... \$\endgroup\$
    – Mr. Xcoder
    Aug 11, 2017 at 13:54
  • 1
    \$\begingroup\$ Just looking at the docs (I know nothing about Ohm), could you do 2~? \$\endgroup\$ Aug 11, 2017 at 14:18
  • \$\begingroup\$ @TEHProductions Oh, much better. Thanks! \$\endgroup\$ Aug 11, 2017 at 14:20
1
\$\begingroup\$

Factor + grouping.extras, 41 bytes

[ head-clump rest [ 1 kth-largest ] map ]

Try it online!

  • head-clump rest Prefixes without the first
  • [ 1 kth-largest ] map Map each to the second-largest element
\$\endgroup\$
1
\$\begingroup\$

Arturo, 45 44 bytes

$->a->map..2size a=>[last chop sort take a&]

Try it

$->a->                  ; a function taking an argument a
    map..2size a => [   ; map over the indices of a sans the first few
        last            ; the last element
        chop            ; of a block without its last element
        sort            ; sorted
        take a &        ; prefix of input given current index
    ]                   ; end map
\$\endgroup\$
0
\$\begingroup\$

Mathematica, 45 bytes

Sort[s[[;;i]]][[-2]]~Table~{i,2,Length[s=#]}&

Try it online!

\$\endgroup\$
0
\$\begingroup\$

Swift 3, 67 bytes

func g(l:[Int]){print((1..<l.count).map{l[0...$0].sorted()[$0-1]})}

Test Suite.

Swift 3, 65 bytes

{l in(1..<l.count).map{l[0...$0].sorted()[$0-1]}}as([Int])->[Int]

Test Suite.


How to run these?

The first one is a complete function that takes the input as a function parameter and prints the result. You can use them exactly as shown in the testing link. I decided to add instructions though, because the second type of function is used very rarely and most people don't even know of its existence. Usage:

g(l: [1, 1, 2, 2, 3, 3, 4] )

The second one is an anonymous function, like lambdas. You can use it exactly as you'd do it Python, declaring a variable f and calling it:

var f = {l in(1..<l.count).map{l[0...$0].sorted()[$0-1]}}as([Int])->[Int]

print(f([1, 1, 2, 2, 3, 3, 4]))

or wrap it between brackets and call it directly ((...)(ArrayGoesHere)):

print(({l in(1..<l.count).map{l[0...$0].sorted()[$0-1]}}as([Int])->[Int])([1, 1, 2, 2, 3, 3, 4]))
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.