Code golf: combining multiple sorted lists into a single sorted list

前端 未结 26 1840
余生分开走
余生分开走 2020-12-29 12:42

Implement an algorithm to merge an arbitrary number of sorted lists into one sorted list. The aim is to create the smallest working programme, in whatever language you like.

相关标签:
26条回答
  • 2020-12-29 12:55

    Javascript

    function merge(a) {
        var r=[], p;
        while(a.length>0) {
            for (var i=0,j=0; i<a.length && p!=a[j][0]; i++)
                if (a[i][0]<a[j][0])
                    j = i;
    
            r.push(p = a[j].shift());
    
            if (!a[j].length)
                a.splice(j, 1);
        }
        return r;
    }
    

    Test:

    var arr = [[1, 4, 7], [2, 5, 8], [3, 6, 9]]​;
    alert(merge(arr));
    
    0 讨论(0)
  • 2020-12-29 12:55

    VB is usually not the language of choice for code golf, but here goes anyway.

    The setup -

    
            Dim m1 As List(Of Integer) = New List(Of Integer)
            Dim m2 As List(Of Integer) = New List(Of Integer)
            Dim m3 As List(Of Integer) = New List(Of Integer)
            Dim m4 As List(Of Integer) = New List(Of Integer)
    
            m1.Add(1)
            m1.Add(2)
            m1.Add(3)
    
            m2.Add(4)
            m2.Add(5)
            m2.Add(6)
    
            m3.Add(7)
            m3.Add(8)
            m3.Add(9)
    
            Dim m5 As List(Of List(Of Integer)) = New List(Of List(Of Integer))
            m5.Add(m1)
            m5.Add(m2)
            m5.Add(m3)
    

    An attempt in VB.NET (without sort)

            While m5.Count > 0
                Dim idx As Integer = 0
                Dim min As Integer = Integer.MaxValue
                For k As Integer = 0 To m5.Count - 1
                    If m5(k)(0) < min Then min = m5(k)(0) : idx = k
                Next
                m4.Add(min) : m5(idx).RemoveAt(0)
                If m5(idx).Count = 0 Then m5.RemoveAt(idx)
            End While
    

    Another VB.NET attempt (with an allowed sort)

    
        Private Function Comp(ByVal l1 As List(Of Integer), ByVal l2 As List(Of Integer)) As Integer
            Return l1(0).CompareTo(l2(0))
        End Function
        .
        .
        .
        While m5.Count > 0
            m5.Sort(AddressOf Comp)
            m4.Add(m5(0)(0)) : m5(0).RemoveAt(0)
            If m5(0).Count = 0 Then m5.RemoveAt(0)
        End While
    

    The entire program -

            Dim rand As New Random
            Dim m1 As List(Of Integer) = New List(Of Integer)
            Dim m2 As List(Of Integer) = New List(Of Integer)
            Dim m3 As List(Of Integer) = New List(Of Integer)
            Dim m4 As List(Of Integer) = New List(Of Integer)
            Dim m5 As List(Of List(Of Integer)) = New List(Of List(Of Integer))
            m5.Add(m1)
            m5.Add(m2)
            m5.Add(m3)
    
            For Each d As List(Of Integer) In m5
                For i As Integer = 0 To 100000
                    d.Add(rand.Next())
                Next
                d.Sort()
            Next
    
            Dim sw As New Stopwatch
            sw.Start()
            While m5.Count > 0
                Dim idx As Integer = 0
                Dim min As Integer = Integer.MaxValue
                For k As Integer = 0 To m5.Count - 1
                    If m5(k)(0) < min Then min = m5(k)(0) : idx = k
                Next
                m4.Add(min) : m5(idx).RemoveAt(0)
                If m5(idx).Count = 0 Then m5.RemoveAt(idx)
            End While
            sw.Stop()
    
            'Dim sw As New Stopwatch
            'sw.Start()
            'While m5.Count > 0
            '    m5.Sort(AddressOf Comp)
            '    m4.Add(m5(0)(0)) : m5(0).RemoveAt(0)
            '    If m5(0).Count = 0 Then m5.RemoveAt(0)
            'End While
            'sw.Stop()
    
            Console.WriteLine(sw.Elapsed)
            Console.ReadLine()
    
    0 讨论(0)
  • 2020-12-29 12:56

    Ruby: 100 characters (1 significant whitespace, 4 significant newlines)

    def m(i)
      a=[]
      i.each{|s|s.each{|n|a.insert((a.index(a.select{|j|j>n}.last)||-1)+1,n)}}
      a.reverse
    end
    

    Human version:

    def sorted_join(numbers)
      sorted_numbers=[]
    
      numbers.each do |sub_numbers|
        sub_numbers.each do |number|
          bigger_than_me = sorted_numbers.select { |i| i > number }
          if bigger_than_me.last
            pos = sorted_numbers.index(bigger_than_me.last) + 1
          else
            pos = 0
          end
    
          sorted_numbers.insert(pos, number)
        end
      end
    
      sorted_numbers.reverse
    end
    

    This can all just be replaced by numbers.flatten.sort

    Benchmarks:

     a = [[1, 4, 7], [2, 4, 8], [3, 6, 9]]
     n = 50000
     Benchmark.bm do |b|
       b.report { n.times { m(a) } }
       b.report { n.times { a.flatten.sort } }
     end
    

    Produces:

          user     system      total        real
     2.940000   0.380000   3.320000 (  7.573263)
     0.380000   0.000000   0.380000 (  0.892291)
    

    So my algorithm performs horribly, yey!

    0 讨论(0)
  • 2020-12-29 12:57

    F#: 116 chars:

    let p l=
        let f a b=List.filter(a b) in
        let rec s=function[]->[]|x::y->s(f(>)x y)@[x]@s(f(<=)x y) in
        [for a in l->>a]|>s
    

    Note: this code causes F# to throw a lot of warnings, but it works :)

    Here's the annotated version with whitespace and meaningful identifiers (note: the code above doesn't use #light syntax, the code below does):

    let golf l=
        // filters my list with a specified filter operator
        // uses built-in F# function
        // ('a -> 'b -> bool) -> 'a -> ('b list -> 'b list)
        let filter a b = List.filter(a b)
    
        // quicksort algorithm
        // ('a list -> 'a list)
        let rec qsort =function
            | []->[]
            | x :: y -> qsort ( filter (>) x y) @ [x] @ qsort ( filter (<=) x y)
    
        // flattens list
        [for a in l ->> a ] |> qsort
    
    0 讨论(0)
  • 2020-12-29 12:57

    BASH in about 250 essential chars

    BASH is not really good at list manipulation, anyway this is does the job.

    # This merges two lists together
    m(){ 
        [[ -z $1 ]] && echo $2 && return; 
        [[ -z $2 ]] && echo $1 && return; 
        A=($1); B=($2); 
        if (( ${A[0]} > ${B[0]} ));then 
            echo -n ${B[0]}\ ;
            unset B[0];
        else 
            echo -n ${A[0]}\ ;
            unset A[0];
        fi;
        m "${A[*]}" "${B[*]}";
    }
    # This merges multiple lists
    M(){
        A=$1;
        shift;
        for x in $@; do
            A=`m "$A" "$x"`
        done
        echo $A
    }
    
    $ M '1 4 7' '2 5 8' '3 6 9'
    1 2 3 4 5 6 7 8 9
    
    0 讨论(0)
  • 2020-12-29 12:57

    VB

    The setup:

    Sub Main()
        f(New Int32() {1, 4, 7}, _
          New Int32() {2, 5, 8}, _
          New Int32() {3, 6, 9})
    End Sub
    

    The output:

    Sub f(ByVal ParamArray b As Int32()())
        Dim l = New List(Of Int32)
        For Each a In b
            l.AddRange(a)
        Next
        For Each a In l.OrderBy(Function(i) i)
            Console.WriteLine(a)
        Next
    End Sub
    
    0 讨论(0)
提交回复
热议问题