Take the 2-minute tour ×
Programming Puzzles & Code Golf Stack Exchange is a question and answer site for programming puzzle enthusiasts and code golfers. It's 100% free, no registration required.

Say i have a list (unorder):

Score = ['score1','score10','score6','score2','score22','score12']
Names = ['name1','name10','name6','name2','name22','name12']
email = ['email1','email10','email6','email2','email22','email12']

and then Score is sorted to be

ScoreSorted = ['score1','score2','score6','score10','score12','score22'].

The shortest code (in byte) to sort Name and Email with Score list wins

result of email and names list should be

EmailSorted = ['email1','email2','email6','email10','email12','email22'].
NamesSorted = ['name1','name2','name6','name10','name12','name22'].
share|improve this question

closed as unclear what you're asking by Keith Randall, Jan Dvorak, xfix, Peter Taylor, Timtech Jan 6 at 11:49

Please clarify your specific problem or add additional details to highlight exactly what you need. As it's currently written, it’s hard to tell exactly what you're asking. See the How to Ask page for help clarifying this question.If this question can be reworded to fit the rules in the help center, please edit the question.

    
It's not clear whether you're expecting ScoreSorted to be input, output, or neither. –  Peter Taylor Jan 6 at 10:26
    
So, we have a list A, and a list A' which is a permutation of A, and then for a given list B we should find the same permutation B'? –  marinus Jan 6 at 13:31
    
@marinus I interpretted the problem as the following: given a list A with a logical lexicographical ordering, sort this list, and apply the same permutation to both B and C. This is analogous to sorting data rows in a spreadsheet by a specific column. –  primo Jan 7 at 4:43
add comment

4 Answers

up vote 2 down vote accepted

Ruby 81 bytes

m=Score.each_index.sort_by{|i|Score[i]}
p m.map{|i|Names[i]}
p m.map{|i|Email[i]}

A golfed implemention of the algorithm below, assuming Score, Names, and Email are all already defined, and that only output of the post-sorted Names and Email is required.

Sample usage:

Score = ['score1','score10','score6','score2','score22','score12']
Names = ['name1','name10','name6','name2','name22','name12']
Email = ['email1','email10','email6','email2','email22','email12']

m=Score.each_index.sort_by{|i|Score[i]}
p m.map{|i|Names[i]}
p m.map{|i|Email[i]}

Sample output:

["name1", "name10", "name12", "name2", "name22", "name6"]
["email1", "email10", "email12", "email2", "email22", "email6"]

Ruby (with natural sort) 123 bytes

m=Score.each_index.sort_by{|i|Score[i].scan(/\d+|\D+/).map{|i|i=~/\d/?i.to_i: i}}
p m.map{|i|Names[i]}
p m.map{|i|Email[i]}

Correctly sorts strings with any number of digital groupings, as one would sort them 'naturally'. The only caveat is that all strings in the Score array must start with a digit, or all must start with a non-digit.

Sample output:

["name1", "name2", "name6", "name10", "name12", "name22"]
["email1", "email2", "email6", "email10", "email12", "email22"]

Python

Not a code-golf answer.

  1. Find the inverse permutation of the list which is to be sorted in lexicographical order (in the problem description, this Scores array). This can be achieved in O(n log n) time (as the problem is analog to sorting), although the implementation below is O(n²).
  2. Apply this permutation to each list. The permute function is O(n) complexity.

Sample implementation:

def get_inv_perm(items):
  size = len(items)
  perm = [0]*size
  for i in range(size):
    for j in range(size): perm[j] += items[j] > items[i]
  return perm

def permute(arr, perm):
  size = len(arr)
  out = [0] * size
  for i in range(size):
    val = perm[i]
    out[i] = arr[val]
  return out

if __name__ == "__main__":
  Score = ['score1','score10','score6','score2','score22','score12']
  Names = ['name1','name10','name6','name2','name22','name12']
  Email = ['email1','email10','email6','email2','email22','email12']

  perm = get_inv_perm(Score)

  print permute(Score, perm)
  print permute(Names, perm)
  print permute(Email, perm)

Sample output:

['score1', 'score10', 'score12', 'score2', 'score22', 'score6']
['name1', 'name10', 'name12', 'name2', 'name22', 'name6']
['email1', 'email10', 'email12', 'email2', 'email22', 'email6']

Because the sort is lexicographical, score10 and score12 appear directly after score1. The get_inv_perm function assumes the items list is unique. The remaining lists need not be.

share|improve this answer
add comment

Ruby 108 bytes

[names, email, score].map do |z|
  z.sort! {|x, y| x.scan(/\d/).join.to_i <=> y.scan(/\d/).join.to_i }
end
puts "#{names}\n#{email}\n#{score}"
share|improve this answer
add comment

C++ 117 bytes

#define S(a)a##Sorted.push_back(a[i])
for(auto a:ScoreSorted){int i=0;for(auto b:Score)a==b?S(Names),S(Email),0:++i;}

Notice that I am making two assumptions:

  • strings vectors for to represent all lists
  • it is OK to capitalize the name of the unsorted email list (email -> Email)

Sample usage:

#include <string>
#include <vector>
#include <iostream>

using namespace std;

int main()
{
    vector<string> Score = {"score1","score10","score6","score2","score22","score12"};
    vector<string> Names = {"name1","name10","name6","name2","name22","name12"};
    vector<string> Email = {"email1","email10","email6","email2","email22","email12"};

    vector<string> ScoreSorted = {"score1","score2","score6","score10","score12","score22"};
    vector<string> NamesSorted;
    vector<string> EmailSorted;

#define S(a)a##Sorted.push_back(a[i])
for(auto a:ScoreSorted){int i=0;for(auto b:Score)a==b?S(Names),S(Email),0:++i;}

    for (auto i : NamesSorted) {
        cout << i << endl;
    }
    for (auto i : EmailSorted) {
        cout << i << endl;
    }
}
share|improve this answer
add comment

Python, 172 bytes. Assumes names and emails are unique. Not particularly efficient as you have to do a lookup for each comparison.

NamesSorted=sorted(Names,lambda l,r:cmp(Score[Names.index(l)],Score[Names.index(r)]))
EmailSorted=sorted(email,lambda l,r:cmp(Score[email.index(l)],Score[email.index(r)]))
share|improve this answer
add comment

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