19
\$\begingroup\$

The Challenge

Display the alphabet from a given letter read from console input. If the letter is uppercase, you have to display the alphabet uppercased. The alphabet printed must end in the precedent letter of the one inserted. If an additiontal parameter is added to the input (a simple dot .) the alphabet should be printed one letter in each line. Otherwise, the alphabet should be printed in the same line, separed by a simple space. If wrong input is send to the program it will not print anything.

Inputs examples:

Input:

c

Program's ouput:

d e f g h i j k l m n o p q r s t u v w x y z a b

Input

H.

Program's ouput:

I
J
K
L
M
N
O
P
Q
R
S
T
U
V
W
X
Y
Z
A
B
C
D
E
F
G
\$\endgroup\$
8
  • \$\begingroup\$ Sage Notebook operates at the "console level", so is the required "console input" in this case just typing the input into a worksheet cell? \$\endgroup\$
    – r.e.s.
    Commented Aug 21, 2012 at 13:41
  • \$\begingroup\$ shortest code wins? \$\endgroup\$
    – ardnew
    Commented Aug 21, 2012 at 16:16
  • \$\begingroup\$ @ardnew Yes, shortest code wins. \$\endgroup\$
    – Averroes
    Commented Aug 22, 2012 at 6:10
  • \$\begingroup\$ @r.e.s. I think that while you need to code the input reading of some way it can be fair from the rules perspective. \$\endgroup\$
    – Averroes
    Commented Aug 22, 2012 at 6:11
  • 6
    \$\begingroup\$ @Averroes The penalty for using GolfScript is the amount of time it takes to learn a language which has no real use outside of this kind of competition. I don't think penalising people for using the right tool for the job is going to be very productive. \$\endgroup\$
    – Gareth
    Commented Aug 23, 2012 at 11:50

30 Answers 30

12
\$\begingroup\$

GolfScript 48 75 73 70 67 66 63 57 53

(91,65>.+.{32+}%+.@?>(;25<''+.,1>*\['''.']?[' 'n 0]=*

Online demos:

Update:

Now the last rule is also implemented. Thanks to Ventero for pointing out the issue.

Update:

I rewrote the code from scratch and found new ways to shorten it even further.

History of modifications:

.,3<\(:x;:§['''.']?)and{91,65>.+.{32+}%+.x?).{>25<''+{§n' 'if}%}{;;}if}''if
.,3<\(:x;:§['''.']?)*{91,65>.+.{32+}%+.x?).{>25<''+{§n' 'if}%}{;;}if}''if
.,3<\(:x;:§['''.']?)*{91,65>.+.{32+}%+.x?).!!@@>25<''+{§n' 'if}%*}''if
.,3<\(:x;:§['''.']?)*!!91,65>.+.{32+}%+.x?).!!@@>25<''+{§n' 'if}%**
.,3<\(:x;:§['''.']?)*91,65>.+.{32+}%+.x?).@@>25<''+{§n' 'if}%@@*!!* 
.(@,3<@:§['''.']?)*91,65>.+.{32+}%+@1$?).@@>25<''+{§n' 'if}%@@*!!*
.(@,3<@:§['''.']?)*91,65>.+.{32+}%+@1$?):x>25<''+{§n' 'if}%\x*!!*
.(@,3<@:§['''.']?)*91,65>.+.{32+}%+@1$?):x>25<''+§n' 'if*\x*!!*
(\:§['''.']?)91,65>.+.{32+}%+@1$?):x>25<''+§n' 'if*\x*!!*
(91,65>.+.{32+}%+.@?>(;25<''+.,1>*\['''.']?[' 'n 0]=* 
\$\endgroup\$
6
  • 2
    \$\begingroup\$ This solution does not follow the last requirement: If wrong input is send to the program it will not print anything. \$\endgroup\$
    – Ventero
    Commented Aug 21, 2012 at 17:21
  • \$\begingroup\$ @Ventero Right. I'll fix this. \$\endgroup\$ Commented Aug 21, 2012 at 19:18
  • \$\begingroup\$ 63 - nice, we're head2head :), wish I could understand golfscript ;) \$\endgroup\$
    – bua
    Commented Aug 23, 2012 at 11:30
  • \$\begingroup\$ I feel the same way about Q. Great job! ;-) \$\endgroup\$ Commented Aug 23, 2012 at 11:32
  • \$\begingroup\$ +1 awesome! willing to break 50 ;-) ? \$\endgroup\$
    – bua
    Commented Aug 24, 2012 at 16:00
10
\$\begingroup\$

C, 135 129 128 chars

Damn, so many different magic numbers, but no way to get rid of them.

Has to be run with the input as program parameter. Now follows the "wrong input" requirement.

c;main(a,b)char**b;{if(a==2&&isalpha(**++b)&&!(c=1[*b])||c==46&&!2[*b])for(;++a<28;)printf("%c%c",**b-=**b+6&31?-1:25,c?10:32);}

Explanation:

c;                   // Variable that will be used later
main(a,b)char**b;{   // There's one parameter => a = 2, b[1] = the parameter
                     // Wrong input checks: We want...
  if(
     a==2 &&         // 1 parameter and ...
     isalpha(**++b)  // lower- or uppercase letter as parameter,
                     // increase b so we can access it better
     &&              // and ...
     !(c=1[*b]) ||   //   either no further character,
                     //     save the character in c, or...
     (c==46&&!2[*b]) //   a dot as next character and no further characters
    )                // if check succeeded, execute the for loop, else do nothing
  for(;++a<28;)      // This will loop 26 times (2..27)
    printf("%c%c",   // Print two characters
                     // First character to print:
      **b            // We'll print the first character of the parameter,
       -=            // but decrement it before printing
       **b+6&31?     // if the last five bits (31 = 11111b) are not 26 (6 == -26 mod 32)
        -1           //   decrement it by -1 (aka increment it)
        :25,         //   else (char=z/Z) decrement by 25, so we start over at a/A
                     // Second character to print:
      c?             // c is either ASCII 0 or a dot (ASCII 46)
       10            //   dot     -> print a newline
       :32);         //   ASCII 0 -> print a space (ASCII 32)
}

The **b+6&31 part uses the fact that the ASCII codes for lowercase/uppercase character are the same if only looking at the last 5 bits and the remaining 5 bits are in range 1..26.

Version without "wrong input" requirement (82 chars):

main(a,b)char**b;{for(b++;++a<28;)printf("%c%c",**b-=**b+6&31?-1:25,1[*b]?10:32);}
\$\endgroup\$
6
  • \$\begingroup\$ Any instruction on how to compile it? I get Segmentation fault when running. \$\endgroup\$
    – manatwork
    Commented Aug 21, 2012 at 14:20
  • \$\begingroup\$ @manatwork seems to take the input as parameter. \$\endgroup\$
    – shiona
    Commented Aug 21, 2012 at 14:28
  • \$\begingroup\$ Yes, indeed, edited to clarify. E.g. if the program name is test, call it like test c or test X. \$\endgroup\$
    – schnaader
    Commented Aug 21, 2012 at 14:31
  • \$\begingroup\$ Thanks, got it. My C seems to be rustier than I thought. \$\endgroup\$
    – manatwork
    Commented Aug 21, 2012 at 14:35
  • 2
    \$\begingroup\$ K&R definition style can help: main(a,b)char**b;{. Also, one b++ would let you replace *b[1]->**b and b[1][1]->1[*b]. \$\endgroup\$
    – ugoren
    Commented Aug 21, 2012 at 18:59
7
\$\begingroup\$

Ruby, 72 71 61 characters

gets;25.times{$><<$_=$_.succ[0]+=$1?$/:' '}if~/^[a-z](\.)?$/i

This ruby version uses a regular expression to verify the input. Fortunately, the Ruby string method succ does most of the work for us (including the wrap-around).

Edit: 61 characters with the help of chron and Ventero.

\$\endgroup\$
4
  • \$\begingroup\$ Mine ended up way too similar to yours to bother posting separately. Same approach, but a few characters shorter (65): c=gets[0];25.times{$><<c.next![-1]+($1?$/:' ')}if~/^[a-z](\.)?$/i \$\endgroup\$ Commented Aug 24, 2012 at 2:17
  • 2
    \$\begingroup\$ And this is 62: gets;25.times{$><<$_=$_.next[0]+($1?$/:' ')}if~/^[a-z](\.)?$/i - basically the same as yours just abusing $_ and $/ \$\endgroup\$ Commented Aug 24, 2012 at 2:35
  • 2
    \$\begingroup\$ @chron: Using += instead of +, you can drop the parentheses around $1?$/:' '. \$\endgroup\$
    – Ventero
    Commented Aug 24, 2012 at 11:14
  • \$\begingroup\$ @chron and Ventero: Thank you. Added your code to my solution. \$\endgroup\$
    – Howard
    Commented Aug 25, 2012 at 9:39
6
\$\begingroup\$

Ruby: 127 113 92 (?) characters

(I can't find the rule about the penalty score on using -p. Added 1 for now. If wrong, please correct me.)

$_=if ~/^([a-z])(\.)?$/i;s,e=$1>?Z?[?a,?z]:[?A,?Z];[*$1.succ..e,*s...$1]*($2==?.?$/:" ")end

Sample run:

bash-4.2$ ruby -pe '$_=if ~/^([a-z])(\.)?$/i;s,e=$1>?Z?[?a,?z]:[?A,?Z];[*$1.succ..e,*s...$1]*($2==?.?$/:" ")end' <<< c
d e f g h i j k l m n o p q r s t u v w x y z a b

bash-4.2$ ruby -pe '$_=if ~/^([a-z])(\.)?$/i;s,e=$1>?Z?[?a,?z]:[?A,?Z];[*$1.succ..e,*s...$1]*($2==?.?$/:" ")end' <<< H.
I
J
K
L
M
N
O
P
Q
R
S
T
U
V
W
X
Y
Z
A
B
C
D
E
F
G

bash-4.2$ ruby -pe '$_=if ~/^([a-z])(\.)?$/i;s,e=$1>?Z?[?a,?z]:[?A,?Z];[*$1.succ..e,*s...$1]*($2==?.?$/:" ")end' <<< seven
\$\endgroup\$
6
\$\begingroup\$

Ruby, 101 95

i,d=gets.split''
[*?a..?z].join[/#{i}/i]
($'+$`).chars{|c|$><<(i>?Z?c:c.upcase)+(d==?.?$/:' ')}

Try it online

\$\endgroup\$
3
  • \$\begingroup\$ Does not follow "If wrong input is send to the program it will not print anything." \$\endgroup\$
    – Matt
    Commented Aug 21, 2012 at 20:36
  • \$\begingroup\$ could save a few chars with ('a'..'z').to_a => [*?a..?z] \$\endgroup\$ Commented Aug 22, 2012 at 4:11
  • \$\begingroup\$ @chron Thanks! How could I miss that.. \$\endgroup\$
    – defhlt
    Commented Aug 22, 2012 at 5:39
6
\$\begingroup\$

GolfScript, 80 72 Characters

.).46={;)}*25,{65+.32+}%?)\""=*!!\([{)..31&26-!26*-}25*;]n+\"."=n" "if**

Lots of the code is testing for valid input and the "print nothing"-option. The actual logic is 37 characters only.

Test cases online

\$\endgroup\$
6
\$\begingroup\$

q/k4 66 64 63 60 58 56 + 2 penalty

penalty for global variable init, algorithm is 56 as below:

56:

if[&/x in".",l:(a;A)90>*x;1@/1_,/|_[0,l?x;l,'"  \n"@#x]]

58:

if[&/x in".",l:(a;A)90>*x;1@/(1_,/|_[0,l?x;l]),'"  \n"@#x]
  • change from if-else to if allowed to reorganize code and get rid of ";" at the end

60:

1@/$[&/x in".",l:(a;A)90>*x;1_,/|_[0,l?x;l];" "],'"  \n"@#x;
  • eventually got rid of this redundant check

63:

1@/$[&/x in".",l:(a;A)90>*x;1_,/|_[0,l?x;l];" "],'" \n""."in x; 
  • print chars recursively instead a whole object
  • still can't get off identity comparsion x in "." in two places... :(
  • semicolon at the end is required, otherwise print function (1@) would print it's return value to stdout.... damn

64:

2@,/$[&/x in".",l:(a;A)90>*x;1_,/|_[0,l?x;l];" "],'" \n""."in x;  

EDIT:

Added penalty of 2 for global initialization(x:), same if wrapping function into brackets (as slackware suggested)
not sure if changing namespace should be punished as well...then it's another 3

(.Q`a`A) instead of (a;A)

Example:

q)\         - switch interpreter to k4
 \d .Q     - change to native namespace
  x:"c"
  if[&/x in".",l:(a;A)90>*x;1@/1_,/|_[0,l?x;l,'"  \n"@#x]]
d e f g h i j k l m n o p q r s t u v w x y z a b

  x:"@"
  if[&/x in".",l:(a;A)90>*x;1@/1_,/|_[0,l?x;l,'"  \n"@#x]]    
  x:"H."
  if[&/x in".",l:(a;A)90>*x;1@/1_,/|_[0,l?x;l,'"  \n"@#x]]
I
J
K
L
M
N
O
P
Q
R
S
T
U
V
W
X
Y
Z
A
B
C
D
E
F
G
  x:...
\$\endgroup\$
3
  • \$\begingroup\$ +1 Nice progress. I'll try to find another way to shorten my code now. \$\endgroup\$ Commented Aug 23, 2012 at 9:25
  • \$\begingroup\$ Can it really be called valid k if it's using definitions in q.k? ;-) Also, if you wrap it in a function, you can skip the x:"a" setup step, eg {$[...]} \$\endgroup\$
    – skeevey
    Commented Aug 24, 2012 at 15:02
  • \$\begingroup\$ @slackwear you're right, that's why it's called q/k4 ;-). \$\endgroup\$
    – bua
    Commented Aug 24, 2012 at 16:02
6
\$\begingroup\$

Perl, 131 127 117 112 106 104 102 98 96 92 91 90 93 71 66 65 64 58 characters

s!^([a-z])(\.?)$!print chop,$2?$/:$"for($1..az)[1..25]!ie

Usage:

perl -ne 's!^([a-z])(\.?)$!print chop,$2?$/:$"for($1..az)[1..25]!ie'

One character has been added to the count for the n option.

Largest cut was only possible because of seeing the behaviour of ++ on characters in Jon Purdy's answer.

\$\endgroup\$
4
  • \$\begingroup\$ You can shave off a couple chars by removing the last 2 semicolons \$\endgroup\$
    – ardnew
    Commented Aug 21, 2012 at 20:33
  • 1
    \$\begingroup\$ this thing is impressive \$\endgroup\$
    – bua
    Commented Aug 23, 2012 at 14:25
  • \$\begingroup\$ @bua Thanks, I'm still trying to find the characters so that I can catch you and w0lf. :-) \$\endgroup\$
    – Gareth
    Commented Aug 23, 2012 at 14:31
  • \$\begingroup\$ s/a.$1/az/ to save 2 more. chop().($2?$/:$") --> chop,$2?$/:$" for 4 more \$\endgroup\$
    – mob
    Commented Sep 7, 2012 at 21:30
5
\$\begingroup\$

Perl, 149, 167

Update

  • Added sanity check.
  • Took ardnew suggestion about the separator application.
exit if $ARGV[0] !~ /[a-z]\.?/i;    # sanity check input
($x,$d)=split //,$ARGV[0];          # split input arguments
@l=65..90;                          # define uc letter range
push @l,splice @l,0,ord(uc $x)-64;  # rotate letter range
pop @l;                             # remove the argument letter
print join $d?$/:$",                # print the joined list
  map {ord($x)>90?lc chr:chr} @l;   # map chr and lc as appropriate
\$\endgroup\$
1
  • \$\begingroup\$ you can replace $s=($d)?"\n":" "; with $s=$d?$/:$"; and maybe just get rid of $s altogether \$\endgroup\$
    – ardnew
    Commented Aug 21, 2012 at 15:55
4
\$\begingroup\$

Python, 83

r=raw_input()
i=ord(r[0])
exec"i+=1-26*(i%%32>25);print chr(i)%s;"%","["."in r:]*26
\$\endgroup\$
2
  • \$\begingroup\$ I'm not a fan of this restriction, but it exists and you program does not follow it: "If wrong input is send to the program it will not print anything." \$\endgroup\$
    – Matt
    Commented Aug 21, 2012 at 12:20
  • \$\begingroup\$ Also, it looks like you print one character more than you should. The example output is 25 characters. \$\endgroup\$
    – Matt
    Commented Aug 21, 2012 at 12:24
4
\$\begingroup\$

PHP, 120 119 113

<?$v=fgets(STDIN);$f=$c=$v[0];ctype_alpha($c++)||die;for(;$c[0]!=$f;$c=$c[0],$c++)echo$c[0],$v[1]=='.'?"\n":" ";
\$\endgroup\$
2
  • 1
    \$\begingroup\$ This is a code-golf challenge, so speed and resource usage optimizations are not needed. Instead of storing $v[1]=='.'?"\n":" "'s result in variable $s, let PHP calculate it each time in the echo statement. That way you can spare 6 characters. \$\endgroup\$
    – manatwork
    Commented Aug 21, 2012 at 15:41
  • 1
    \$\begingroup\$ @manatwork Thank you, I changed it. \$\endgroup\$
    – lortabac
    Commented Aug 21, 2012 at 15:47
4
\$\begingroup\$

Mathematica 158 159 204 199 183 167 165 162

Code

f@h_ := Most@RotateLeft[#, Position[#, h][[1, 1]]] &[FromCharacterCode /@ 
        (65~Range~90 + 32 Boole@LowerCaseQ@h)];
g = Characters@# /. {{p_} :> Row[f@p, " "], {p_, "."} :> Column@f@p, _ -> ""} &

Usage

g["c"]
g["H"]
g["H."]
g["seven"]

usage

\$\endgroup\$
2
  • \$\begingroup\$ Third usage case is f["H"] or f["H."]? \$\endgroup\$
    – Averroes
    Commented Aug 21, 2012 at 12:33
  • \$\begingroup\$ I had to fix the handling of ".", adding 50 chars to the code. But it now works according to the instructions \$\endgroup\$
    – DavidC
    Commented Aug 21, 2012 at 13:23
3
\$\begingroup\$

J 43

|:1j1#(25{.(u:,2#65 97+/i.26)(>:@i.}.[)])"0

Examples:

|:1j1#(25{.(u:,2#65 97+/i.26)(>:@i.}.[)])"0 's'

t u v w x y z a b c d e f g h i j k l m n o p q r

|:1j1#(25{.(u:,2#65 97+/i.26)(>:@i.}.[)])"0 's.'

t
u
v
w
x
y
z
a
b
c
d
e
f
g
h
i
j
k
l
m
n
o
p
q
r

|:1j1#(25{.(u:,2#65 97+/i.26)(>:@i.}.[)])"0 '['

This solution evolved on the J programming forum: http://jsoftware.com/pipermail/programming/2012-August/029072.html

Authors: AlvordBossCerovskiCyrEllerHuiLambertMcCormickMillerQuintanaSchottSherlockTaylorTherriault

Explanation

J phrases are executed starting on the right, passing the on-going result to the left as it gets evaluated. Since it's interactive, we can look at pieces of the solution in isolation to better understand them.

The middle part generates the upper and lower case alphabet in Unicode:

   u:,2#65 97+/i.26
ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz

The " u: " verb converts its numeric right argument to Unicode characters. The numeric argument is generated from the ASCII values for the upper- and lower-case characters by adding the numbers for "A" and "a" each to the values from 0 to 25 generated by "i.26":

   65 97+/i.26
65 66 67  68  69  70  71  72  73  74  75  76  77  78  79  80  81  82  83  84  85  86  87  88  89  90
97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122

The right-hand portion,

   ((>:@i.}.[)])"0

looks up ( i. ) the position of the right argument ( ] ) in the left ( [ ) - which is the vector of letters above - and drops ( }. ) one more ( >: ) than that number. The ' "0 ' applies this phrase to 0-dimensional (scalar) arguments.

   ('123H999' (>:@i.}.[)])"0 'H'
999

The " 25 {. " phrase takes the first 25 elements of the vector on the right.

The penultimate phrase " 1j1 # " on the left replicates its right argument according the number on the left. A simple number does a simple replication:

   2 # 'ABCD'
AABBCCDD

However, a complex number - indicated by the " j " between the real and imaginary portions - inserts a fill element according to the imaginary part. Here we indicate one fill element by the one to the right of the " j ".

   2j1 # 'ABCD'
AA BB CC DD 

As with most J primitives, the replicate verb ( # ) works on numeric arrays in an analagous fashion to how it works on character arrays. As shown here,

   1j1 # 1 2 3
1 0 2 0 3 0

we see that the default numeric fill element is zero whereas for characters it is the space character.

Finally, the leftmost token " |: " transposes the result of the preceding verbs to its right.

Explanation provided by Devon McCormick. Thank you Devon.

\$\endgroup\$
2
  • \$\begingroup\$ +1 Really nice solution and explanation. I considered trying it in J but couldn't figure a good way (a short way) to check that the input was valid. I think mine would have been at least twice as long as this. \$\endgroup\$
    – Gareth
    Commented Sep 6, 2012 at 22:54
  • \$\begingroup\$ Thanks Gareth, If you look at the early solutions in the discussion link, you will see many of our starts were longer. One of the neat things we found was the variety of approaches that we could use with J. cheers, bob \$\endgroup\$ Commented Sep 6, 2012 at 23:30
3
\$\begingroup\$

brainfuck, 303

,>,>++++++[-<-------->]<++[[-]+++++[->++++<]>++<]>++++++++++<<[->+>>>+<<<<]>>>>>>+++++++++++++++[-<++++++<<++++++>>>]<[<[->>]>[>>]<<-]<[[-]++++++++[-<++++>]]<<<[->>>+>+<<<<]>>>>>+[[-]<.<<<.>[->>>+>+<<<<]>>>[-<<<+>>>]<[->+>-<<]>[-<+>]+>[-<[-]>]<[++++[-<----->]<->]<+[->+>+<<]<[->+>-<<]>[-<+>]>>[-<<+>>]<]

Currently it doesn't support the If wrong input is send to the program it will not print anything part, and it can probably be shorter. I plan on fixing it later. Right now my brain is too ****ed to continue.

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

C, 110

Sometimes prints "spaces" between letters, sometimes not.

i,j;main(int c,char*l){gets(l);l[1]&=10;j=*l%32;c=*l&~31;for(i=j;i<j+25;i++){l[0]=c+i%26+1;printf("%2s",l);}}

Slighly more readable:

i,j;
main(int c,char*l)
{
  gets(l);
  l[1]&=10;          // makes . to line feed and some other chars to "start of text" 
                     // which looks like space in some cases 
                     // (the byte can become either 0, 2, 8 or 10)

  j=*l%32;           // 0b 000c cccc, these five bits code which letter was chosen
  c=*l&~31;          // 0b ccc0 0000, these three bits code upper/lowercase

                     // 0b ccc0 0000 + (0b 000c cccc + [0..24])%26 + 1
  for(i=j;i<j+25;i++){l[0]=c+i%26+1;printf("%2s",l);}
}

Runs:

$ ./a.out
G
 H I J K L M N O P Q R S T U V W X Y Z A B C D E F

$ ./a.out
p.
q
r
s
t
u
v
w
x
y
z
a
b
c
d
e
f
g
h
i
j
k
l
m
n
o
\$\endgroup\$
2
\$\begingroup\$

JavaScript, 137

Unfortunately a bit verbose (String.fromCharCode and charCodeAt).

for(x=b=(n=prompt(m={122:97,90:65})).charCodeAt(r='');/^[a-z]\.?$/i.test(n)&&(x=m[x]||x+1)!=b;)r+=String.fromCharCode(x)+(n[1]?"\n":" ");
\$\endgroup\$
2
\$\begingroup\$

Perl, 77 76 70 68

chomp(($a,$b)=split//,<>);$"=$/if$b;map{++$a=~/(.)$/}1..25;print"@a"

Edits:

  1. Saved a character using regex instead of substr.

  2. Saved 6 characters using map instead of for.

  3. Saved 2 characters by omitting final newline.

\$\endgroup\$
3
  • 3
    \$\begingroup\$ Nice, but as you've pointed out it doesn't meet the requirement that invalid input gives no output. Fix that and you'll get my upvote. \$\endgroup\$
    – Gareth
    Commented Aug 21, 2012 at 19:09
  • \$\begingroup\$ doesn't seem to work for me on perl 5.14.2. also i dont believe the \n in your final print is required, which will save a couple chars \$\endgroup\$
    – ardnew
    Commented Aug 21, 2012 at 20:44
  • \$\begingroup\$ @ardnew: I wrote it on my work computer, which has 5.12.3. Will kill the \n, thanks. \$\endgroup\$
    – Jon Purdy
    Commented Aug 21, 2012 at 22:41
2
\$\begingroup\$

R, 219

Ugly, long... still works.

f=function(l){if(!nchar(l)%in%c(1,2))invisible()else{s=ifelse(nchar(l)==1," ","\n");l=substr(l,1,1);v=letters;if(l%in%v){}else v=LETTERS;l=grep(l,v);if(l==26)cat(v[1:25],sep=s)else cat(c(v[l+1:(26-l)],v[1:l-1]),sep=s)}}

Usage:

f("a")
f("c.")
f("H")
f("z")
f("Z.")
f("seven")
\$\endgroup\$
2
\$\begingroup\$

C, 146 chars (terrible)

main(){char b[100];gets(b);for(char a=b[0],c=a,d=a&223,e=b[1];++c!=a&64<d&d<91&(!e|e==46&!b[2]);(c&31)>26?(c&=96):(putchar(c),putchar(e?10:32)));}

I'm not very experienced in C, which probably shows... >.< I had a feeling that chars being integers would be helpful, but it didn't actually seem to make as big of an impact as I hoped... I'll leave my attempt here though, feel free to suggest improvements.

Unminified version:

main() {
  char b[999]; // assume that the line will fit in 999 chars...
  gets(b);

  // a is the char we start on, c is the char that we iterate,
  // d is toUppercase(a), e is just an alias for the second char.
  for (char a = b[0], c = a, d = a&223, e=b[1];
      // increment c, make sure that we haven't reached a yet.
      // also check the other conditions (first char is letter, second char
      // is either '.' or NULL, third char is NULL if second char was '.').
      ++c != a & 64 < d & d < 91 & (!e | e == 46 & !b[2]);
      (c&31) > 26     // check if we need to wrap around
        ? (c &= 96)   // if so, wrap
        : (putchar(c), putchar(e?10:32))  // otherwise, print char & separator
  );
}
\$\endgroup\$
2
\$\begingroup\$

VBA 225

Formatted to run from the immediate window:

s=InputBox(""):n=Asc(Left(s,1)):l=Len(s):p=IIf(l<3,IIf(l=2,IIf(Right(s,1)=".",vbCr,"")," "),""):c=IIf(n>64 And n<91,65,IIf(n>96 And n<123,97,99)):o=n-c+1:If o>0 And p<>"" Then For i=o To o+24:x=x & Chr(i Mod 26+c) & p:Next:?x

Broken down into individual lines (needs to be surrounded by Sub block and needs a different print method to work in a module, thus making the code longer):

s=InputBox("")
n=Asc(Left(s,1))
l=Len(s)
p=IIf(l<3,IIf(l=2,IIf(Right(s,1)=".",vbCr,"")," "),"")    
c=IIf(n>64 And n<91,65,IIf(n>96 And n<123,97,99))
o=n-c+1
If o>0 And p<>"" Then 
For i=o To o+24
x=x & Chr(i Mod 26+c) & p
Next
End If 'Not needed when completed in single line format
MsgBox x
\$\endgroup\$
2
\$\begingroup\$

Java 8, 127 bytes

a->{String r="",d=a.length>1?"\n":" ";char c=a[0],C=c;for(;++c<(c<97?91:123);r+=c+d);for(c=C<97?64:'`';++c<C;r+=c+d);return r;}

Explanation:

Try it online.

a->{                        // Method with character-array parameter and String return-type
  String r="",              //  Result-String, starting empty
         d=a.length>1?      //  If the length of the input is larger than 1
            "\n"            //   Set the delimiter to a new-line
           :                //  Else:
            " ";            //   Set the delimiter to a space
  char c=a[0],              //  Get the input letter
       C=c;                 //  And create a copy of it
  for(;++c<(c<97?91:123);   //  Loop from this letter + 1 to (and including) 'Z'/'z'
    r+=c+d);                //   And append the result with a letter + the delimiter
  for(c=C<97?64:'`';++c<C;  //  Loop again from 'A'/'a' to (and excluding) the input-letter
    r+=c+d);                //   And append the result with a letter + the delimiter
  return r;}                //  Return the result
\$\endgroup\$
1
\$\begingroup\$

Mumps, 91, 86, 82,79,76

r t i t?1A.1"." s a=$A(t),p=a>90*32+65 f i=1:1:25 w *(a+i-p#26+p) w:t["." !

Not such a modern language ;) I'm sure there's a bit of optimization space left..

Explanation:

r t 

read input

i t?1A.1"."

check if t matches the required input

s a=$A(t),p=a>90*32+65 f i=1:1:25 { w *(a+i-p#26+p) w:t["." !}

basic for loop through the alphabet. Note that mumps is strictly evaluating left to right. True=1, so you get 65 or 97 as a result for p, # is the modulo operator

tests:

USER>d ^golf
d.e
f
g
h
i
j
k
l
m
n
o
p
q
r
s
t
u
v
w
x
y
z
a
b
c

USER>d ^golf
tuvwxyzabcdefghijklmnopqrs
USER>d ^golf
h.i
j
k
l
m
n
o
p
q
r
s
t
u
v
w
x
y
z
a
b
c
d
e
f
g

USER>d ^golf
hallo
USER>

(you'll need a mumps runtime env, ie Caché to run this this)

edit: bold heading

edit: had a wrong solution, fixed now. Thanks to rtfs and Averroees for pointing this out

\$\endgroup\$
3
  • \$\begingroup\$ the code appears to be 79 chars in length, not 80 \$\endgroup\$ Commented Aug 24, 2012 at 7:19
  • \$\begingroup\$ unfortunately the first space is not optional, so I thought I have to count it in. \$\endgroup\$ Commented Aug 24, 2012 at 7:25
  • \$\begingroup\$ The test cases doesn't ends in the precedent letter of the one passed as parameter, does them? \$\endgroup\$
    – Averroes
    Commented Aug 24, 2012 at 9:12
1
\$\begingroup\$

JavaScript: 141

c="",b=c[0].charCodeAt()<91,a="abcdefghijklmnopqrstuvwxyz",b&&(a=a.toUpperCase()),a=a.split(c[0]),a=a[1]+a[0],a=c[1]?a.split("").join("\n"):a

Commented version:

c="", //write input here (examples "a", "B", "c.", "D.")
b=c[0].charCodeAt()<91, //true for upperC, false for lowerC
a="abcdefghijklmnopqrstuvwxyz", //the abc
b&&(a=a.toUpperCase()), //if upper, turn main string to upperC
a=a.split(c[0]), //split by the first char of input
a=a[1]+a[0], //swap the two parts
a=c[1]?a.split("").join("\n"):a //if input second char, add breaklines in between
//the output is inside 'a'

jsFiddle DEMO

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

Here is my first attempt at it with APL.

⍞{1 1≡(2⌈⍴⍺)⍴⍺∊'.',⍵:⊃(~=/2⍴⍺)⌷(,X,' ')(X←25 1⍴1↓(X⍳⊃⍺)⌽X←(⎕A∊⍨⊃⍺)⌷2 26⍴⍵)}6↓26⌽⎕UCS 65+⍳58

if I can use a single global variable A←2 26⍴6↓26⌽⎕UCS 65+⍳58 then I can shorten the above down to the following:

{1 1≡(2⌈⍴⍵)⍴⍵∊'.',,A:⊃(~=/2⍴⍵)⌷(,X,' ')(X←25 1⍴1↓(X⍳⊃⍵)⌽X←(⎕A∊⍨⊃⍵)⌷A)}⍞
\$\endgroup\$
0
\$\begingroup\$

C++11

#include <iostream>
#include <vector>
#include <cstdio>

int main(int argc, const char * argv[])
{
    std::vector<char> list1,list2;
    for( char c = 'a'; c <='z'; c++ )
    {
        list1.push_back( c );
        list2.push_back( toupper( c ) );
    }
    char c = getchar();
    auto f = [ c ]( std::vector<char> list )
    {
        auto i = std::find( list.begin(), list.end(), c );
        if( i == list.end() )
            return;
        auto c = i;
        for( ;; )
        {
            c++;
            if( c == list.end() ) c = list.begin();
            if( c == i )break;
            std::cout<<*c<<"\n";
        }
    };
    f( list1 );f(list2);
    return 0;
}
\$\endgroup\$
0
\$\begingroup\$

C (111)

main(int i, char**c){if(isalpha(*c[1]))for(i=0;i<25;i++) printf("%c",isalpha((*c[1])+1)?++*c[1]:(*c[1]-=25));}

dissection

if(isalpha(*c[1])) // start with char-check.

for(i=0;i<25;i++) // we need 25 values, excluding input char. reusing i.

printf("%c", // print char. ofcourse.

isalpha((*c[1])+1) ? ++*c[1] : (*c[1]-=25)); 
//check if we are past z/Z and fall back to a/A. 
//make that available to print. 

Works]$ ./test 5

Works]$ ./test W XYZABCDEFGHIJKLMNOPQRSTUV

Works]$ ./test M NOPQRSTUVWXYZABCDEFGHIJKL

Works]$ ./test g hijklmnopqrstuvwxyzabcdef

Works]$ ./test [

Works]$ ./test a bcdefghijklmnopqrstuvwxyz

Works]$ ./test Z ABCDEFGHIJKLMNOPQRSTUVWXY


Thank you for some food for thought.

\$\endgroup\$
2
  • \$\begingroup\$ You're not adding newlines if a '.' is given. Also, you should not output anything if the input isn't [A-Za-z]\.?, if I understood the question right. \$\endgroup\$
    – marinus
    Commented Sep 28, 2012 at 22:01
  • \$\begingroup\$ #1. oh! i was engrossed in making code short.. #2. see the output of 'test [' it printss nothing. @marinus \$\endgroup\$
    – essbeev
    Commented Oct 5, 2012 at 6:00
0
\$\begingroup\$

Perl, 226 characters

die "Invalid input " if $ARGV[0] !~ /[a-z]\.?/i;
@listA=(a...z);
$index=ord(lc(substr($ARGV[0],0,1)))-97;
print join(substr($ARGV[0],1) ? "\n" : " ",map{$ARGV[0] =~ /[A-Z]/?uc $_:$_}(@listA[$index+1...25],@listA[0...$index]));
\$\endgroup\$
2
  • \$\begingroup\$ You can format your text to appear as a code block. Read the guide here to formatting your posts. Also, you can save some characters by using single character variable names. \$\endgroup\$
    – Gareth
    Commented Sep 5, 2012 at 11:44
  • 1
    \$\begingroup\$ An invalid input should print nothing, so your die statement can be reduced, saving a bunch... \$\endgroup\$
    – Gaffi
    Commented Feb 5, 2013 at 14:50
0
\$\begingroup\$

C# 170

using System.Linq;namespace N{class P{static void Main(string[]a){foreach(char e in"abcdefghijklmnopqrstuvwxyz".ToCharArray().Where(o =>o>'c'))System.Console.Write(e);}}}

Uncompressed

using System.Linq;
namespace N {
    class P {
        static void Main(string[]a){
            foreach (char e in "abcdefghijklmnopqrstuvwxyz".ToCharArray().Where(o => o > 'c'))
                System.Console.Write(e);
        }
    }
}
\$\endgroup\$
3
  • \$\begingroup\$ Don't forget to add an explanation to your answer. \$\endgroup\$
    – Justin
    Commented Feb 20, 2014 at 20:46
  • \$\begingroup\$ This program doesn't even by far try to play by the rules. 1: If the letter is uppercase, you have to display the alphabet uppercased. 2: The alphabet printed must end in the precedent letter of the one inserted. 3: If an additiontal parameter is added to the input (a simple dot .) the alphabet should be printed one letter in each line. Otherwise, the alphabet should be printed in the same line, separed by a simple space. 4: If wrong input is send to the program it will not print anything. This is a 4-out-of-4 miss. \$\endgroup\$
    – RobIII
    Commented Feb 21, 2014 at 1:07
  • \$\begingroup\$ ^ Other than that I urge you to take a look at my earlier comments here. You can replace char with var and shave 1 point of your score, loose the .ToCharArray() (a string is a char-array you can already iterate over!), lose the string[] a since you're not dealing with commandline arguments, lose the namespace, Your constant 'c' should be read from console input, lose the alphabet string and use ASCII instead etc. It's great that you play, but please try to make a decent effort; most submissions of yours seem to be trolling only. \$\endgroup\$
    – RobIII
    Commented Feb 21, 2014 at 1:10
0
\$\begingroup\$

C, 117

main(c,s,d){d=c=getchar(),s=getchar();for(s=s<0?32:s^46?0:10;d+=d+6&31?1:-25,s&&isalpha(c)&&d^c;printf("%c%c",d,s));}

Credit to schnaader for the d+6&31 trick.

http://ideone.com/ts1Gs9

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

Bash: 110 bytes

(([[ $1 =~ [a-z] ]]&&echo {a..z})||([[ $1 =~ [A-Z] ]]&&echo {A..Z}))|([ "${1:1:1}" = . ]&&sed 's/ /\n/g'||cat)

In terms of explanation, it's pretty straightforward, no magic tricks - this is just something that bash is intrinsically well suited for. In terms of the non-obvious bits:

  • {a..z} is a very underused trick in bash - it expands to a b c d.... You can do the same to generate numerical sequences.
  • Bash can do regex matching, [[ $1 =~ [a-z] ]] runs a regex match against the first program argument for characters from a to z. Likewise for A-Z. You need double square brackets for it though, [ can't do it.
  • ${1:1:1} gets a substring of $1 (the first argument), one character in, one character long - that is, it returns the second character of the string, what we expect to be ..
  • sed 's/ /\n/g' simple regex: searches and replaces spaces with newlines. If . is the second character of the string, we pipe input to this, or otherwise...
  • cat is the final trick here - if we don't want to replace spaces with newlines, we feed stdin to cat instead which simply outputs it again.
\$\endgroup\$
1
  • \$\begingroup\$ Don't forget to add an explanation. \$\endgroup\$
    – Justin
    Commented Feb 21, 2014 at 1:01

Your Answer

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

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