0
\$\begingroup\$

Ok lets say we get a input the following csv file (all entries are quoted strings)

ID,    Before,   After,   Value 
 1,         3,       5,    Cat
 2,         5,        ,    Apple
 3,         4,       1,    Dog
 4,          ,       3,    Elephant
 5,         1,       2,    Banana

Output a csv file in which the entries are usage sequence order.

ID,    Before,   After,   Value
 2,         5,        ,    Apple 
 5,         1,       2,    Banana
 1,         3,       5,    Cat
 3,         4,       1,    Dog
 4,          ,       3,    Elephant

Notes: The Values may not necessarily appear in alphabetical order all the time, just that in this example they are. No revaluing of the IDs being use. They must be the same as input.

Input and Output files will be pass as args to program.

\$\endgroup\$
  • \$\begingroup\$ What column are we ordering on? Will there always be the same columns? \$\endgroup\$ – Josh Feb 7 '14 at 18:51
  • \$\begingroup\$ @Josh We're not ordering on any column, just using the Before and After values to figure it out. First 3 columns will always be the same. \$\endgroup\$ – Adam Speight Feb 7 '14 at 19:03
  • \$\begingroup\$ I'm still not grasping the concept. What do before and after refer to? How are they ordered in the example solution? They look out of order to me. \$\endgroup\$ – Josh Feb 7 '14 at 19:05
  • \$\begingroup\$ @Josh The before and after refer to which ID that this entry appears before and after. Take a look at the first and last entries of the output. \$\endgroup\$ – Adam Speight Feb 7 '14 at 19:11
  • \$\begingroup\$ I see now. What do we do if the input has no possible solution? \$\endgroup\$ – Josh Feb 7 '14 at 19:14
1
\$\begingroup\$

Ruby 109 108

Saved one whole character by using randomization instead of searching!

h,*t=[*$<]
t.shuffle!until t.each_cons(2).all?{|c|a,b=c.map{|y|y.lstrip.split /[,\s]+/}
a[1]==b[0]}
puts h,t

This only prints to stdout, so to save to a file use ruby csv.rb in.csv > out.csv.

$ cat test.csv 
ID,    Before,   After,   Value 
 1,         3,       5,    Cat
 2,         5,        ,    Apple
 3,         4,       1,    Dog
 4,          ,       3,    Elephant
 5,         1,       2,    Banana
$ ruby csv.rb test.csv 
ID,    Before,   After,   Value 
 2,         5,        ,    Apple
 5,         1,       2,    Banana
 1,         3,       5,    Cat
 3,         4,       1,    Dog
 4,          ,       3,    Elephant

Old version

puts gets,[*$<].permutation.find{|x|x.each_cons(2).all?{|c|a,b=c.map{|y|y.lstrip.split /[,\s]+/}
a[1]==b[0]}}

It simply finds the permutation of the lines where, for each line, the second column (Before) equals the first column (ID) of the next line.

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

VB.net (Non-Golfed)

Module Module3
  Public Sub Main(ParamArray args() As String)
    Dim items = CSVFileReader(args(0)).ToDictionary(Function(x) x(0))
    Dim Current = items.First(Function(kvp) kvp.Value(2) = "").Value
    Using out As New IO.StreamWriter(args(1), False) With {.AutoFlush=True }
      Do
        out.WriteLine("""{0}"",""{1}"",""{2}"",""{3}""", Current(0), Current(1), Current(2), Current(3))
        If Current(1) <> "" Then Current = items(Current(1))
      Loop Until Current(1) = ""
      out.WriteLine("""{0}"",""{1}"",""{2}"",""{3}""", Current(0), Current(1), Current(2), Current(3))
    End Using
  End Sub

  Public Iterator Function CSVFileReader(fn As String) As IEnumerable(Of String())
    Using t As New FileIO.TextFieldParser(fn) With {.Delimiters ={","},.HasFieldsEnclosedInQuotes = True, .TextFieldType=FileIO.FieldType.Delimited }
      While Not t.EndOfData
        Yield t.ReadFields
      End While
    End Using
  End Function
End Module

Probably a lot of room to golf that code.

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

C#, 272 bytes

Not a great answer, but it works. If I understand Linq correctly, this opens the input file repeatedly, once for each line it writes to the output.

namespace System.Linq{
    class P{
        static void Main(string[]a)
        {
            var v=IO.File.ReadAllLines(a[0]).Select(y=>y.Split(',').ToList());
            var l=v.First();
            var s="\"\"";
            for(;;){
                IO.File.AppendAllText(a[1],string.Join(",",l)+"\n");
                l=v.FirstOrDefault(x=>x[2]==s);
                if(l==null)break;
                s=l[0];
            }
        }
    }
}

Input file:

"ID","Before","After","Value"
"1","3","5","Cat"
"2","5","","Apple"
"3","4","1","Dog"
"4","","3","Elephant"
"5","1","2","Banana"

Output file:

"ID","Before","After","Value"
"2","5","","Apple"
"5","1","2","Banana"
"1","3","5","Cat"
"3","4","1","Dog"
"4","","3","Elephant"
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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