Find columns where all characters are the same

21

4

I came across this question on SO and thought it'd make a nice golf challenge. So here it is:

Challenge:

Write a program that reads a sequence of character strings, one per line, and outputs a list of all positions where each string has the same character.

Input and output:

The input consists of one or more lines of printable non-whitespace ASCII characters, each followed by a newline. You may assume that all input lines have the same length. The newline is not to be considered part of the input (i.e. you should not output it as a matching character).

Example input (shamelessly stolen from the SO question):

abcdefg
avcddeg
acbdeeg

After reading the input, your program should print the positions of each matching column and the characters they contain. (Your program may, but need not, stop reading further input if it can determine early that there are no matching columns.) Any reasonable output format is permitted; in particular, you may use either 0-based or 1-based indexing for the positions.

Example output for the above input (using 0-based indexing):

0: a
3: d
6: g

Scoring:

This is code golf, so shortest answer wins. In the event of a tie, fractional tie-breaker chars may be awarded for additional features:

  • −½ chars for correctly handling input lines of unequal length. (Output should not contain positions past the end of the shortest input line.)
  • −¼ chars for correctly handling input consisting of arbitrary UTF-8 encoded Unicode characters.

For inspiration, you may find some ungolfed solutions at the SO question (see above).

Clarifications:

  • Simply concatenating the positions and characters, as in 0a3d6g, does not count as "reasonable output". You should provide some kind of separator (such as a space) between each element of the output so that it can be parsed unambiguously.

  • The input will be provided on the standard input stream (stdin), or using whatever text file input mechanism is most natural to your language of choice. (If your chosen language doesn't have a natural mechanism for file input, do whatever seems closest in spirit.)

  • The input ends when there is no more data to be read (i.e. when an end-of-file condition occurs). If you wish, you may require that the input be terminated by a blank line (which you then should not count as part of the input, obviously). If you do so, please mention it in your answer so that others can provide correct input for testing.

  • Every input line, including the last one, ends with a newline character. Your answer must not report this newline as a matching column. (It's fine if your solution can also handle input where the last line doesn't end in a newline, but that's not required.)

Ilmari Karonen

Posted 2012-01-17T14:55:44.333

Reputation: 19 513

So does a blank line terminate input? – Steven Rumbalski – 2012-01-17T15:52:41.480

"You should provide some kind of separator between each element of the output so that it can be parsed unambiguously." Does a space count as a seperator? – Steven Rumbalski – 2012-01-17T16:03:49.293

@StevenRumbalski: The input ends when there's no more data to read; I guess I can allow a trailing blank line if your language has trouble detecting EOF. And yes, a space is a perfectly good separator. – Ilmari Karonen – 2012-01-17T16:44:58.603

Can we have some arbitrary UTF-8 encoded Unicode characters sample code? – user unknown – 2012-01-18T02:18:09.190

Answers

1

05AB1E (legacy), score: \$9\frac{1}{4}\$ (10 bytes - \$\frac{3}{4}\$ for both bonuses)

|ø€Ùā‚øʒнg

Outputs with 1-based indexing.

Try it online.

Uses the legacy version, because ø worked with a list of strings whereas the new version would need an explicit €S to convert each inner string to a list of characters first. It does mean I can't use the builtin of the new version though, which pairs each item with its 0-based index. As alternative I use ā‚ø to pair with its 1-based index.

In the new 05AB1E version this would therefore have been 11 bytes: |€Sø€Ù.āʒнg - Try it online (with 0-based indexing instead).

Explanation:

|           # Push all input-lines as a list
 ø          # Zip/transpose; swapping rows/columns,
            # which implicitly discards any trailing characters for the 1/2 bonus
  €Ù        # Uniquify each inner string/character-list
    ā       # Push a list in the range [1, length] (without popping the list of strings)
     ‚      # Pair it with the list of strings
      ø     # Zip/transpose again, which pairs each string with its 1-based index
       ʒ    # Filter this list of string-index pairs by:
        н   #  Where the first item (the string)
         g  #  Has a length equal to 1 (note: only 1 is truthy in 05AB1E)
            # (after which the result is output implicitly)

Kevin Cruijssen

Posted 2012-01-17T14:55:44.333

Reputation: 67 575

13

APL, 25 characters

∩/{0=⍴⍵:⍬⋄(⊂⍵,⍨¨⍳⍴⍵),∇⍞}⍞

I used Dyalog APL (version 13) as my interpreter. It handles both inputs of unequal length and Unicode (UTF-8) characters.

Examples:

      ∩/{0=⍴⍵:⍬⋄(⊂⍵,⍨¨⍳⍴⍵),∇⍞}⍞
abcdefg
avcddeg
acbdeeg

  1 a  4 d  7 g  

      ∩/{0=⍴⍵:⍬⋄(⊂⍵,⍨¨⍳⍴⍵),∇⍞}⍞
test日本
blat日本国foo

  4 t  5 日  6 本 

Explanation, somewhat from right to left:

  • The main chunk of this answer is the direct function (basically, anonymous function), defined within the curly braces. Its right argument is specified by .
    • 0=⍴⍵:⍬ is our first expression, and it checks if we've gotten an empty line (i.e., we are done). It uses a guard (a familiar construct to many functional programmers) to conditionally execute the expression to the right of the colon. In this case, if 0 is equal to the shape/length () of the right argument, we return the empty set ().
    • separates the two expressions within the function. If the previous expression didn't get evaluated (and thus didn't return anything), we move to the next expression.
    • We recursively call the function using the self-reference function (). The argument to the function is a line of non-evaluated user input, given by quote-quad ().
    • ⊂⍵,⍨¨⍳⍴⍵ creates pairs for each character in the string, where each pair's first element is its position in the string, and its second element is the character.
    • ⍳⍴⍵ gives a vector from 1 to ⍴⍵, or the length of the input string.
    • ⍵,⍨¨ applies the commuted concatenation function (,⍨) to each (¨) element to its left (, in this case the user's input) and right. Commuting the concatenation function causes its left and right arguments to be swapped.
    • Finally, we enclose the result using , so that we can differentiate between lines of input.
  • We initially feed our function with user input ().
  • Finally, we reduce (/) our resulting vector of vectors of pairs using the intersection function (), yielding the pairs that are found in all of the sub-vectors.

Dillon Cower

Posted 2012-01-17T14:55:44.333

Reputation: 2 192

For no good reason I have a visceral negative response whenever I see APL that I don't have for J or GolfScript. But +1 anyway for an excellent solution. – Steven Rumbalski – 2012-01-20T01:01:50.170

1I've actually been thinking about switching to J... I'll tack that on my list of reasons. :) – Dillon Cower – 2012-01-21T02:35:45.403

12

Golfscript (28 chars)

n/zip:^,,{.^=.&.,1>{;;}*}%n*

There are character set issues when piping Unicode through, so no quarter-point bonus.

Peter Taylor

Posted 2012-01-17T14:55:44.333

Reputation: 41 901

1+1. This should not have less upvotes than my answer. – Steven Rumbalski – 2012-01-19T16:49:26.133

10

J, 57 51 44 40 characters

,.&.>y;y{{.z[y=.I.*/2=/\]z=.];._2]1!:1]3

I'm getting there slowly but surely. This is still far from ideal though I think.

I felt sure that using a hook would be the answer but unfortunately not (44 chars):

,.&.>((];({{.)~)([:I.[:*/2=/\]))];._2]1!:1]3

I may need a completely different method to get any shorter.

Gareth

Posted 2012-01-17T14:55:44.333

Reputation: 11 678

1+1. But yes, I expect better from J. – Steven Rumbalski – 2012-01-17T18:54:24.070

This should not have less upvotes than my answer. – Steven Rumbalski – 2012-01-19T16:49:59.940

1@StevenRumbalski The upvotes don't always reflect the relative sizes of the code. It sometimes becomes a language popularity contest. I agree that the golfscript answer should be up there with the APL, unfortunately I've already given it my upvote and can't help push it up further. – Gareth – 2012-01-19T17:05:57.400

8

Python 2, score 81.5 (116 94 86 83 82 bytes minus bonus)

import sys
i=0
for x in zip(*sys.stdin)[:-1]:
 i+=1
 if len(set(x))<2:print i,x[0]

Steven Rumbalski

Posted 2012-01-17T14:55:44.333

Reputation: 1 353

+1 for a nice Python golf but You can lose a whole FOUR characters: [:-1] isn't necessary unless to strip off an extraneous newline at the end of the input (which does not even seem to be there in the question). – ChristopheD – 2012-01-17T22:41:24.240

@ChristopheD: Actually, the result of zip(*sys.stdin) is [('a', 'a', 'a'), ('b', 'v', 'c'), ('c', 'c', 'b'), ('d', 'd', 'd'), ('e', 'd', 'e'), ('f', 'e', 'e'), ('g', 'g', 'g'), ('\n', '\n', '\n')]. I don't see a way around avoiding stripping that last tuple of newlines. Please correct me if I've misunderstood. Thank you for the upvote. – Steven Rumbalski – 2012-01-17T22:48:31.967

If you remove the last newline in your data file the tuple for that line isn't complete (misses one '\n' so zip only considers and returns the data we are looking for, allowing the removal of [:-1]. E.g. zip([1,2,3,4],[1,2,3])=> [(1, 1), (2, 2), (3, 3)] – ChristopheD – 2012-01-17T23:08:54.897

@ChristopheD: Per spec, "input consists of [...] lines [...], each followed by a newline." – Ilmari Karonen – 2012-01-18T10:24:26.530

Steven Rumbalski, @Ilmari Karonen: Sorry, did not see that in the spec. – ChristopheD – 2012-01-18T10:32:23.400

Save a character: len(set(x))<2 – Clueless – 2012-01-18T15:01:17.860

@Clueless: Thank you for the one character. The two characters required for == bothered me. – Steven Rumbalski – 2012-01-18T16:48:08.983

1Would the person who downvoted this answer explain why? – Steven Rumbalski – 2012-01-18T18:53:22.103

FYI: I didn't (still +1) I rarely downvote - not a single one on codegolf.se yet) and if I do i always leave a comment. Just wanted to make sure you knew this since I previously commented on your answer. – ChristopheD – 2012-01-19T23:17:00.917

@ChristopheD. I didn't mean to imply that you downvoted. I really don't care who downvoted. Since downvotes seem pretty rare on codegolf.se I'm curious to know the criticism. It could be something as simple as correcting for the inequity of my answer being in fifth place with respect to character count, but tied for 2nd in votes. – Steven Rumbalski – 2012-01-20T00:58:31.563

8

Haskell, 64 characters

main=interact$show.foldl1(filter.flip elem).map(zip[0..]).lines

Handles lines of unequal length. Unicode support depends on the current locale settings.

Example output:

[(0,'a'),(3,'d'),(6,'g')]

hammar

Posted 2012-01-17T14:55:44.333

Reputation: 4 011

+1. This should not have less upvotes than my answer. – Steven Rumbalski – 2012-01-19T16:49:35.807

5

(Bash) Shell Scripting, 105 characters

If anyone has some more tricks for this, please fill free to comment!

for((i=1;i<`tail -1 $1|wc -c`;i++))do
x="cut -c$i $1";y=`$x`;[ `$x|uniq|wc -l` = 1 ]&& echo $i ${y:3};done

Result:

1 a
4 d
7 g

ChristopheD

Posted 2012-01-17T14:55:44.333

Reputation: 1 599

2ormaaj lacked the rep but wanted to comment: it breaks for Ilmari because of a missing space after the [; and the ${y:3} will cause it to only work with exactly 3 lines of input. Fixing and optimising yields (100 chars) while((++i%\tail -1 $1|wc -c`));do x=`cut -c$i $1`;((`uniq|wc -l`==1))<<<"$x"&&echo $i ${x: -1};doneand using default values should allow saving one more withfor((;++i<`tail -1 $1|wc -c`;))do` but there is an unfixed bug in bash. – Peter Taylor – 2012-02-12T08:08:11.520

I'm having trouble getting this to work; running this on the sample input prints a series of errors like /tmp/cols.sh: line 2: [1: command not found and nothing else. – Ilmari Karonen – 2012-01-18T15:47:06.573

@Ilmari Karonen: this was tested on a Mac (snow leopard, 10.6.2) but should work elsewhere. I'see to have it fixed on Linux tomorrow (should be a small fix) – ChristopheD – 2012-01-18T17:23:18.050

4

Perl, 87 characters (−½ char tie-break bonus)

Here's a golfed version of my own solution from the SO thread:

chomp($a=$b=<>);$a&=$_,$b|=$_ for<>;@$_=$$_=~/./sgfor a,b;$b[$i++]eq$_&&say"$i:$_"for@a

Unlike the SO version, this one uses 1-based indexes for the output. It uses the Perl 5.10 say feature, so needs to be run with perl -M5.010 (or with perl -E).

Like the SO version, this code handles variable-length lines, and would handle arbitrary Unicode input if the standard input and output were in UTF-8 mode. Alas, by default they're not, unless one specifies the non-free -CS command line switch. Thus, it earns the −½ char bonus, but not the −¼ one.

Edit: +1 char to fix a bug: just because the input strings don't contain line feeds doesn't mean they can't end up in $a (e.g. "+" & "J" eq "\n").

Ilmari Karonen

Posted 2012-01-17T14:55:44.333

Reputation: 19 513

1You could save 1 char by using chop instead of chomp. – Toto – 2012-01-18T15:11:17.170

@M42: Good point, although I rather like the robustness of the current version. I think I'll keep the m for now, it's not like it makes any difference to the rankings at the moment. :) – Ilmari Karonen – 2012-01-18T15:24:01.270

3

T-SQL

SELECT N.number, letter = MIN(SUBSTRING(L.line, N.number, 1))
FROM Lines AS L
INNER JOIN master.dbo.spt_values AS N ON N.type = 'P'
WHERE N.number BETWEEN 1 AND (SELECT MAX(LEN(L2.line)) FROM Lines AS L2)
GROUP BY N.number
HAVING COUNT(DISTINCT SUBSTRING(L.line, N.number, 1)) = 1
ORDER BY N.number

Anthony Faull

Posted 2012-01-17T14:55:44.333

Reputation: 131

Hi Anthony, welcome to codegolf. Nice answer - however you are suppose to make it as short as possible. Spaces, long variable names,naming columns, ORDER BY can be omitted, it would be easy to cut away 100+ characters. You should also include the number of characters used in the header. You may find some inspiration in my answer, which is currently half the length – t-clausen.dk – 2020-02-17T09:21:28.620

3

Q, 32

{a!((*:)x)a:(&)1=(#:')(?:')(+)x}

usage

q){a!((*:)x)a:(&)1=(#:')(?:')(+)x}[("abcdefg";"avcddeg";"acbdeeg")]
0| a
3| d
6| g

K, 22

The above solution can be reduced to 22 by writing it completely in K rather than passing K functions to a Q interpreter, reducing the number of parentheses required.

{a!@[*x]a:&1=#:'?:'+x}

tmartin

Posted 2012-01-17T14:55:44.333

Reputation: 3 917

2

Scala 115107: (−¼ for handling UTF-8)

io.Source.stdin.getLines.map(_.zipWithIndex).toList.flatten.groupBy(_._2).map(_._2.toSet).filter(_.size==1)

ungolfed, and Source.fromFile ("f") instead of stdin for better testability:

io.Source.fromFile ("f").
  getLines.map (_.zipWithIndex).
    toList.flatten.groupBy (_._2). 
      map (_._2.toSet).
        filter (_.size==1)

Result:

List(Set((a,0)), Set((g,6)), Set((d,3)))

Thanks to Gareth for the reduction of size 8 for using stdin.

user unknown

Posted 2012-01-17T14:55:44.333

Reputation: 4 210

Can't you use stdin instead of fromFile("f") to save 8 characters? – Gareth – 2012-01-18T13:00:50.023

2

VBA (307.25 284 - 0.75 bonus = 283.25)

I know this has already been won, but here's my shot (not reading a file, just a string - needs to have the io added). I like that I got to use l() recursively. I usually don't have a need for recursion my real-life programming. I only did so much testing, but I believe this covers the unicode bonus point stipulation. It also assumes vbCr is the line terminator. This may not translate to all systems because of that.

Code:

Function a(i)
b=Split(Left(i,Len(i)-1),vbCr):c=UBound(b):For q=1 To Len(b(c)):d=Mid(b(c),q,1):If l(b,c,q,d) Then a=a & q & ": " & d & vbCr:Next
End Function
Function l(m, n, o, p)
If n+1 Then l=IIf(o<=Len(m(n)),Mid(m(n),o,1)=p,0) And l(m,n-1,o,p) Else l=Mid(m(n+1),o,1)=p
End Function

Example input/output:

Debug.Print a("abcdefghijklmnop" & vbCr & "abcdefg" & vbCr & "abcabcghijkl" & vbCr)

1: a
2: b
3: c
7: g

Gaffi

Posted 2012-01-17T14:55:44.333

Reputation: 3 411

1

Burlesque, 16 bytes

ln)XXtpzif{[~sm}

Try it online!

ln   # Split to lines
)XX  # Split each line to chars
tp   # Transpose
zi   # Zip with indices
f{   # Filter for
 [~  # Tail (i.e. chars)
 sm  # All the same
}

DeathIncarnate

Posted 2012-01-17T14:55:44.333

Reputation: 916

1

T-SQL, 134 bytes

This can handle input lines of unequal length

Using 0-based indexing

SELECT n,max(z)FROM(SELECT 
substring(x,number+1,1)z,abs(number)n,*FROM spt_values,@)t
GROUP BY n
HAVING max(z)=min(z)and n<max(len(x))

Try it online

t-clausen.dk

Posted 2012-01-17T14:55:44.333

Reputation: 2 874

1

JavaScript (125 134 140)

for(i=s=[];I=s[++i]=prompt(o='');S=I);for(c=-1;w=r=++c<S.length;o+=r?c+':'+C+'\n':'')for(C=S[c];w<i;)r&=s[w++][c]==C;alert(o)

Demo: http://jsfiddle.net/Fv7kY/4/

Edit 1: Rearrange loops to avoid braces. Initialize i with [] to combine with s. Move w increment into expression.

Edit 2: Set S=I to capture last entered word and save using s[1]. Combine r=1 and ++c<S.length. Set C=s[c] in inner loop and compare to C instead of previous and next words to shorten expression s[w][c]==s[w++][c] to just s[w++][c]==C. Saved a total of 9 characters. Also set w=r=... because when that's true w=1 which is what we need to initialize w with.

mellamokb

Posted 2012-01-17T14:55:44.333

Reputation: 5 544

1

PHP, 123 127 :(

I'm not happy with it (there's bound to be improvements to be had), but here goes:

<?$a=$b=trim(fgets(STDIN));while($l=fgets(STDIN)){$a&=$l;$b|=$l;}$n=-1;while(@$a[++$n]){echo$a[$n]!=$b[$n]?'':"$n:{$a[$n]}\n";}

Proof it works.

If anyone can think of a more clever way of initializing $a and $b, please let me know. Originally I had $a=$b=$n='' and $b eventually was correct, but [empty] & [anything] == [empty], so $a never had content.


Edit: Had to fix newline handling (+6) but dropped closing tag (-2).

Mr. Llama

Posted 2012-01-17T14:55:44.333

Reputation: 2 387

I'm curious, why do you make most of your answers community wiki? – Gareth – 2012-01-17T17:55:03.880

I didn't mean to on this one. Long time ago when I first joined CodeGolf someone told me that it was standard. Have to break the habit. Can un-wiki it now though.

http://codegolf.stackexchange.com/a/2249/1419 (see comments)

– Mr. Llama – 2012-01-17T18:20:38.760

I think it was the standard way of doing things on SO for code golf questions, but not here otherwise no-one would have any reputation at all. :-) – Gareth – 2012-01-17T18:32:01.747

You could probably flag them and ask a moderator to un-CW them. Just explain that it was a mistake.

– Ilmari Karonen – 2012-01-17T18:35:47.487

You could save two chars by leaving out the ?>. However, I just noticed that your code has a bug: it prints an extra match if all lines contain a trailing newline as specified. – Ilmari Karonen – 2012-01-17T20:17:25.873

@IlmariKaronen - It only does that if the final line has a newline at the end of it. If the input is newline delimited, it shouldn't be an issue. ;) – Mr. Llama – 2012-01-17T20:30:37.647

Yeah, but I did specify "lines [...] followed by a newline". Sorry. :/ – Ilmari Karonen – 2012-01-17T20:32:04.493

1

Common Lisp, 183 165 characters

(let((l(loop for m =(read-line)until(equal m "")collect m)))(loop for c across(car l)for i from 0 if(null(remove c(mapcar(lambda(y)(char y i))l)))collect(list i c)))

Readable format:

(let ((l (loop for m = (read-line) until (equal m "") collect m)))
  (loop for c across (car l)
        for i from 0 
        if (null (remove c 
                         (mapcar (lambda(y) (char y i))l)))
        collect(list i c)))

Enter this directly into the REPL and enter lines, terminating with an empty line.

Paul Richter

Posted 2012-01-17T14:55:44.333

Reputation: 770

1

Ruby (71)

a,*s=*$<.lines
(a.size-1).times{|i|s.all?{|t|t[i]==a[i]}&&p([i,a[i]])}

output:

[0, "a"]
[3, "d"]
[6, "g"]

jsvnm

Posted 2012-01-17T14:55:44.333

Reputation: 441

Note: appears to require Ruby 1.9; for Ruby 1.8 compatibility, replace t[i] with t[i,1]. – Ilmari Karonen – 2012-01-19T16:58:04.523

1

C, 126 chars

char a[999],b[999];main(i){for(gets(a);gets(b);)for(i=0;b[i];++i)a[i]^b[i]?a[i]=0:0;
while(i--)a[i]&&printf("%d:%c\n",i,a[i]);}

I've been staring at this but I just can't make it smaller. A new approach may be needed.

(No bonus points; it only handles differently-sized lines if the first line is the shorter one.)

breadbox

Posted 2012-01-17T14:55:44.333

Reputation: 6 893

0

C# with .NET 4 (280)

using c=System.Console;class P{static void Main(){char[]a=c.ReadLine().ToCharArray();int r,i,l=a.Length;m:i=0;n:r=c.Read();if(r>0&&r!=10&&r!=13){if((int)a[i]!=r)a[i]='\0';i++;goto n;}for(;i>0&&i<l;)a[i++]='\0';if(r>0)goto m;for(i=0;i<l;i++)if(a[i]!='\0')c.WriteLine(i+":"+a[i]);}}
  • 1 line, 280 characters
  • Includes all necessary using statements and Main method.
  • Program does not require an empty line at the end, but will accept it
  • Empty lines are ignored
  • Handles input strings of any length.
  • Reserves output until the end (whereas the original answer provided incremental output)

Readable version

    char[]a=c.ReadLine().ToCharArray();
    int r,i,l=a.Length;
    m:
    i=0;
    n:
    r=c.Read();
    if(r>0&&r!=10&&r!=13){
        if((int)a[i]!=r)
            a[i]='\0';
        i++;
        goto n;
    }
    for(;i>0&&i<l;)
        a[i++]='\0';
    if(r>0)
        goto m;
    for(i=0;i<l;i++)
        if(a[i]!='\0')
            c.WriteLine(i+":"+a[i]);

Original answer

using c=System.Console;class P{static void Main(){char[]a;var b=c.ReadLine();a=b.ToCharArray();while(b!=""){for(int i=0;i

  • 1 line
  • 207 characters
  • Includes all necessary using statements and Main method.
  • Program ends when an empty line is entered.
  • Does not handle input strings that are shorter than the first.


Readable version:

    static void Readable()
    {
        char[]a;
        string b=System.Console.ReadLine();
        a=b.ToCharArray();
        while(b.Length>0)
        {
            for (int i = 0; i < a.Length; i++)
            {
                if (a[i] != b[i])
                {
                    a[i] = '\0';
                }
                else
                {
                    System.Console.WriteLine(i+": "+a[i]);
                }
            }
            b=System.Console.ReadLine();
        }
    }

Dr. Wily's Apprentice

Posted 2012-01-17T14:55:44.333

Reputation: 109

Your solution crashes if any line is longer than the first line. – Timwi – 2012-05-09T03:37:46.200

@Timwi Ah...thanks for pointing that out! – Dr. Wily's Apprentice – 2012-05-14T12:40:47.113

When I run this on the test input in the challenge, I get 0: a 1: b 2: c 3: d 4: e 5: f 6: g 0: a 2: c 3: d 6: g 0: a 3: d 6: g. The expected output would be 0: a 3: d 6: g. – Ilmari Karonen – 2012-01-23T22:10:33.280

@Ilmari Ok, but it outputs the columns/characters that are the same after each input line. If you're feeding in a file as the standard input, then the output might seem strange, but if you input manually, I think it makes sense. I will consider how to refactor, though. – Dr. Wily's Apprentice – 2012-01-23T22:13:31.433

0

python 122 characters:

print("\n".join([str(i)+':'+str(x[0]) for i,x in enumerate(zip(*[tuple(x) for x in input().split()])) if len(set(x))<2]))

Ashwini Chaudhary

Posted 2012-01-17T14:55:44.333

Reputation: 169

you don't need a space between ) and for. So instead of …str(x[0]) for i,x…, you can do …str(x[0])for i,x…. It also comes up at tuple(x) for and .split()])) if – Cyoce – 2016-04-04T19:13:46.320

-1

Ruby (242)

s = %w{ abcdefg avcddeg acbdeeg aejdjeggd }
cols = []
s.sort{ |a, b| b.size <=> a.size }[0].size.times do |i|
  uneq=true
  l = s[0][i]
  s.each { |w| uneq = false if l != w[i] }
  cols << [l, i] if uneq
end
cols.each { |c| puts c.join('|') }

agmcleod

Posted 2012-01-17T14:55:44.333

Reputation: 129

you have a ton of unnecessary whitespace. – Cyoce – 2016-04-04T18:59:54.647

The intent of the challenge was to read the lines from standard input. I'm willing to cut some slack for languages (like in-browser JavaScript) where that concept doesn't really exist, but Ruby does have STDIN (or ARGF or just plain gets).

– Ilmari Karonen – 2012-01-18T20:36:50.483

ah okay. But considering STDIN accepts one line, is it to assume something like: "Enter in another line, or 'n' to stop"? Therefore create a loop to build an array. – agmcleod – 2012-01-19T02:00:20.847

I've added some clarifications to the question. Basically, you should keep reading input lines until your reach end-of-file. – Ilmari Karonen – 2012-01-19T16:33:34.320

-1

C#

List<string> strings = new List<string> { "abcdefg", "avcddeg", "acbdeeg", "aejdjeggd" };
var transposes = from index in Enumerable.Range(0, strings.First().Length)
                 select new string((from s in strings select s[index]).ToArray());
int i = 0;
foreach(string transpose in transposes)
{
   if (transpose.Distinct().Count() == 1)
     Console.WriteLine("{0}: {1}", i , transpose[0]);
   i++;
}

Arjang

Posted 2012-01-17T14:55:44.333

Reputation: 99

1Hi, Arjang, and welcome to codegolf.SE! A few comments on your answer: First, since this is a [tag:code-golf] challenge, you're expected to try to make your solution as short as possible; just to start with, you have some long variable names that you could easily shorten to single characters, and some excess whitespace you could remove. (It's fine to post a readable version of your code along with the "golfed" one, but you should actually post a golfed solution too.) Second, if you read the question carefully, I specified that you should read the strings from standard input, not hardcode them. – Ilmari Karonen – 2012-01-21T18:49:32.197