Enumerate a Cell Notation

16

So we're all hopefully familiar with Spreadsheet 'A1' cell notation.

It's simply an alphanumeric representation of the positioning of said cell within a grid. The letter(s) represent the column positioning of the cell, and the number represents the row.

The 'letter' part can consist of 1 or more letters from the 26 letter English alphabet, all of which must be capital letters. These map to numbers through the use of 26-adic bijective numeration. The 'number' part can consist of any positive, non-zero integer.


The challenge, write a program that given the A1 notation of any cell as a single string, can output a string containing the column position represented as a number, followed by a space and then the row number.

Sample Input/Outputs below:

A1
>>1 1
B10
>>2 10
AC4 
>>29 4
AAC753
>>705 753
F123
>>6 123
GL93
>>194 93

This is my first challenge, hence the relative simplicity and potential poorness of the criteria.

EDIT: String must be letters followed by numbers and the winning criteria is the shortest code length (if that can be a thing)

EDIT: Related to this but does the reverse process with a different starting index. Some may argue that this fact makes the linked puzzle more interesting.

dbr

Posted 2017-08-16T00:21:44.073

Reputation: 279

Can we take the input as, for example, an array containing the letters and the numbers: ["A", "1"] – Stephen – 2017-08-16T00:27:24.457

@StepHen I suppose that would be too easy. One of the work is to parse the string. – user202729 – 2017-08-16T00:27:59.177

1@StepHen No. It must be a single string containing both the letters and numbers. I should probably add, also, that the string MUST be in the order of letters followed by numbers. – dbr – 2017-08-16T00:28:16.293

1We usually allow more flexible input and output formats, such as choosing newline instead of space as output separator – Luis Mendo – 2017-08-16T01:17:27.243

@LuisMendo Why is this? Surely part of the challenge is conforming to stricter requirements, otherwise some problems including this one are much more trivial. – dbr – 2017-08-16T01:18:54.930

3@DeanBrunt It depends on you, and of course you can enforce a strict format to make the challenge more difficult. But people usually enjoy the difficulty in the actual computations more than in the format – Luis Mendo – 2017-08-16T01:21:12.760

4It's because the formatting does not add any value to the actual challenge itself – Adnan – 2017-08-16T01:22:57.603

Are we allowed leading space and/or trailing newline? – Greedo – 2017-08-16T12:05:45.087

@Greedo No we're not I'm afraid. – dbr – 2017-08-16T20:49:10.570

Answers

4

05AB1E, 12 11 bytes

áÇ64-₂βð¹þJ

Uses the 05AB1E encoding. Try it online!

Adnan

Posted 2017-08-16T00:21:44.073

Reputation: 41 965

20

Microsoft Excel, 43 Bytes.

=COLUMN(INDIRECT(A1))&" "&ROW(INDIRECT(A1))

I couldn't help myself, I just had to use the right tool for the job. Takes input on A1.

Test Cases

ATaco

Posted 2017-08-16T00:21:44.073

Reputation: 7 898

11

Microsoft Excel, 40 bytes

Brasilian Portuguese language version.

=COL(INDIRETO(A1))&" "&LIN(INDIRETO(A1))

Translated (and therefore golfed) version of ATaco's solution.

pajonk

Posted 2017-08-16T00:21:44.073

Reputation: 2 480

I can't remember if Excel allows this like sheets, but could you use the suggestion by @Uriel on another answer and lose the last 2 parentheses? – dbr – 2017-08-16T20:48:39.180

That suggestion (omitting rightmost parentheses) throws a warning in Excel that you have to confirm to proceed, so I don't think it's allowed here. – pajonk – 2017-08-17T05:37:37.250

Ah I see. It is different to sheets then. – dbr – 2017-08-17T07:07:10.933

7

Python 2, 94 91 73 bytes

-3 bytes thanks to Jonathan Allan
-18 bytes thanks to tsh

s=input().strip
a=s(`3**39`);t=0
for n in a:t=t*26+ord(n)-64
print t,s(a)

Try it online!

This abuses the way that .strip works, removing all digits wtih a=s(`3**39`) where `3**39` is just a shorter way to generate the digits from 0 to 9, this will store only the chars on a that will be used to strip the chars from the numbers on s(a)

Rod

Posted 2017-08-16T00:21:44.073

Reputation: 17 588

I don't think there is a need for strip's input to be the unique characters, so 3**39 should do the same job. – Jonathan Allan – 2017-08-16T01:30:58.473

173 bytes – tsh – 2017-08-16T03:15:09.613

6

Google Sheets, 43 bytes

=COLUMN(INDIRECT(A1))&" "&ROW(INDIRECT(A1))

Try it online!

A1 is the input cell. Hopefully the above link works, I've never tried code golf with Google Sheets before.

notjagan

Posted 2017-08-16T00:21:44.073

Reputation: 4 011

1@ATaco There's no reason to, as duplicate answers can coexist. – Conor O'Brien – 2017-08-16T00:47:50.427

1The appearance of Google Sheets and Microsoft Excel answers pleases me. – dbr – 2017-08-16T00:56:10.847

5you can do =COLUMN(INDIRECT(A1))&" "&ROW(INDIRECT(A1 for 41 bytes. sheets fills in missing right parens. – Uriel – 2017-08-16T12:34:58.987

5

JavaScript, 72 bytes

x=>x.replace(/\D+/,s=>[...s].reduce((n,v)=>n*26+parseInt(v,36)-9,0)+' ')

tsh

Posted 2017-08-16T00:21:44.073

Reputation: 13 072

2

Proton, 113 bytes

k=>{b=(s=k.strip)('0123456789');str(sum(map((a=>26**a[1][0]*(ord(a[1][1])-64)),enumerate(b[to by-1]))))+' '+s(b)}

Try it online!

-19 bytes borrowing Rod's algorithm (note to self: add listcomps)

HyperNeutrino

Posted 2017-08-16T00:21:44.073

Reputation: 26 575

2

Dyalog APL, 44 bytes

(26⊥¯65+⎕AV⍳(a~⎕D)),⎕A~⍨a←⍞

Try it online!

bgiv

Posted 2017-08-16T00:21:44.073

Reputation: 121

1

Remove the parenthesis around (a~⎕D). Look-up in ⎕A instead of ⎕AV. Make tacit. Swap argument of ,. Gets down to only 16 bytes: ~∘⎕A,⍨26⊥⎕A⍳~∘⎕D

– Adám – 2017-08-22T16:20:49.020

1

Pyth - 31 bytes

First attempt, very naive.

jd,s*V.u*26NQ1_hMxLGr-QK@`UTQZK

Try it online here.

Maltysen

Posted 2017-08-16T00:21:44.073

Reputation: 25 023

1

Jelly,  16  15 bytes

ØAɓi@€ḟ0ḅ26,⁸Kḟ

A full program accepting the string as an argument and printing the result

Try it online!

How?

ØAɓi@€ḟ0ḅ26,⁸Kḟ - Main link: list of characters, ref  e.g. "AAC753"
ØA              - uppercase alphabet yield               = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
  ɓ             - dyadic chain separation, call that B and place it on the right
   i@€          - first index for €ach (swap arguments)    [1,1,3,0,0,0]
      ḟ0        - filter discard zeros                     [1,1,3]
        ḅ26     - convert from base 26 to integer           705
            ⁸   - chain's left argument (ref)              "AAC753"
           ,    - pair                                     [705,['A','A','C','7','5','3']]
             K  - join with spaces                         [705,' ','A','A','C','7','5','3']
              ḟ - filter discard those in right (B)        [705,' ','7','5','3']
                - implicit print                        >>>705 753

Note: conversion from a list of numbers using the base conversion atom allows places to be outside of the expected range, so conversion from, say, [2,26,1] ("BZA") using ḅ26 is calculated as 2×262+26×261+1×260=2029 even though the "expected" representation would have been [3,0,1].

Jonathan Allan

Posted 2017-08-16T00:21:44.073

Reputation: 67 804

2@Dean Brunt It is not usual to accept an answer so quickly (most leave it a week) - it may discourage others from competing. I would not be surprised to see this beaten by 05AB1E or another golfing language... – Jonathan Allan – 2017-08-16T01:34:38.307

Point taken. Still learning my way round – dbr – 2017-08-16T01:36:32.950

No problem! Welcome to PPCG, & nice first post :) – Jonathan Allan – 2017-08-16T01:37:07.120

1

Perl 5, 35 + 1 (-p) = 36 bytes

map$r=$r*26-64+ord,/\D/g;s/\D*/$r /

Try it online!

The map statement treats the column like a base26 number and converts it to decimal. The substitution replaces the letters with the numbers. The input and output are implicit in the -p flag.

Xcali

Posted 2017-08-16T00:21:44.073

Reputation: 7 671

1

Mathematica, 108 bytes

StringReplace[c:LetterCharacter..~~r:DigitCharacter..:>ToString@FromDigits[ToCharacterCode@c-64,26]<>" "<>r]

Operator form of StringReplace which takes the alphabetic part c of the string, converts it to a list of character codes, subtracts 64 from each code point, interprets the result as a base 26 integer, converts that integer to a String, then StringJoins a space followed by the numeric part r.

Using a regex (also 108 bytes):

StringReplace[RegularExpression["([A-Z]+)(.+)"]:>ToString@FromDigits[ToCharacterCode@"$1"-64,26]<>" "<>"$2"]

ngenisis

Posted 2017-08-16T00:21:44.073

Reputation: 4 600

1ToCharacterCode@c-64 can sometimes be reduced to LetterNumber@c. LetterNumber does not wrap the output in List when the input is a single character, though. – JungHwan Min – 2017-08-16T01:37:59.767

1

Mathematica, 77 72 69 68 bytes

#/.{a__,b__?DigitQ}:>{f=FromDigits;f[LetterNumber@{a},26],f[b<>""]}&

Takes a list of characters.

Try it on Wolfram Sandbox

Usage

#/.{a__,b__?DigitQ}:>{f=FromDigits;f[LetterNumber@{a},26],f[b<>""]}&[{"G", "L", "9", "3"}]

{194, 93}

or

#/.{a__,b__?DigitQ}:>{f=FromDigits;f[LetterNumber@{a},26],f[b<>""]}&[Characters["GL93"]]

{194, 93}

Explanation

#/.

In the input replace...

{a__,b__?DigitQ}

A list containing two sequences a and b (with 1 or more elements), where b consists of digit characters only... (Mathematica uses lazy pattern matching, so no check is required for a)

:>

into...

f=FromDigits;

Set f to digit-to-integer conversion function.

LetterNumber@{a}

Convert a to letter numbers (a -> 1, b -> 2, etc).

{f[ ... ,26],f[b<>""]}

Convert the above from base-26 to decimal, and convert b to decimal.

JungHwan Min

Posted 2017-08-16T00:21:44.073

Reputation: 13 290

1

Ruby, 50 48+1 = 51 49 bytes

Uses the -p flag. -2 bytes from m-chrzan.

sub(/\D+/){i=0;$&.bytes{|b|i=26*i+b-64};"#{i} "}

Try it online!

Value Ink

Posted 2017-08-16T00:21:44.073

Reputation: 10 608

i=i*26+b-64 saves 2 bytes. – m-chrzan – 2017-08-16T15:49:41.210

1

Ruby, 64 61 59 bytes

->s{s.sub(/\D+/){"#{$&.bytes.reduce(0){|t,b|t*26+b-64}} "}}

Saved 2 bytes thanks to Value Ink.

m-chrzan

Posted 2017-08-16T00:21:44.073

Reputation: 1 390

1$& is the last regex match, so use it instead of m to save 2 bytes. – Value Ink – 2017-08-16T19:59:24.240

1

Excel-VBA Immediate window, 44 45 Bytes (36 35)

Set v=Range([A1]):?trim(v.Column &" "&v.Row);

1 byte added to suppress the trailing newline


Or for 35 with leading whitespace

Set v=Range([A1]):?v.Column""&v.Row

1 byte saved thanks to @TaylorScott!

Both take input from cell A1, output to the VBE Immediate window

Greedo

Posted 2017-08-16T00:21:44.073

Reputation: 267

1I'm gonna go ahead and say that the leading whitespace answer is a valid response as having to remove it would force the use of Trim() on nearly all numeric answers - and on that not I would go with Set v=Range([A1]):?v.Column""&v.Row over your current solution – Taylor Scott – 2017-08-20T20:52:58.803

also, darn, I can't believe I missed this question when it came out! – Taylor Scott – 2017-08-20T20:53:31.197

@TaylorScott Oh nice trick using the "" - I guess Excel knows to insert the ; when the character following Column can't be part of the routine name. I wonder if there's a single character that could do the same thing, probably not. Yes, I would have guessed the leading space would be acceptable for most qus, but for this one I think it's more of a "Print this exact string". I did ask (last comment on question) and was told no leading space or newline. – Greedo – 2017-08-21T10:31:23.480

1also, when I saw the question title, I immediately knew I should have a go if you or someone else hadn't already! As the other Excel-based answers say, right tool for the job. – Greedo – 2017-08-21T10:35:34.887

1

Haskell, 67 bytes

(\(l,n)->show(foldl(\a->(a*26-64+).fromEnum)0l)++" "++n).span(>'9')

Try it online.

Cristian Lupascu

Posted 2017-08-16T00:21:44.073

Reputation: 8 369

1

Retina, 85 bytes

[A-Z]
$& 
[T-Z]
2$&
[J-S]
1$&
T`_L`ddd
\d+
$*
{`\G1(?=.* .* )
26$*
}` (.* )
$1
1+
$.&

Try it online! Explanation:

[A-Z]
$& 

Separate the letters from each other and the final number.

[T-Z]
2$&
[J-S]
1$&
T`_L`ddd

Convert the letters to decimal.

\d+
$*

Convert everything to unary.

{`\G1(?=.* .* )
26$*
}` (.* )
$1

While there are at least three numbers, multiply the first by 26 and add it to the second.

1+
$.&

Convert everything to decimal.

Neil

Posted 2017-08-16T00:21:44.073

Reputation: 95 035

1

><>, 42 Bytes

0i88*-:0(?\$2d**+!
$n88*+48*o\
oi:0(?;   >

Try It Online

Explanation:

0i88*-:0(?\$2d**+! Read in the Letters part of the input
0                  Push an initial 0 to the stack
 i                 Read a character of input
  88*-             Subtract 64 to get from the ascii code to its value ('A'=1,'B'=2 etc.)
      :0(?\        If the value is less than 0, break out of this loop
           $2d**   Multiply our accumulator by 26
                +  Add our new number to the accumulator
                 ! don't add a new zero to the stack

The above loop will read in the first number of the numbers part (eg. '3' in "AB34") before breaking, and will have already subtracted 64 from it, so the next bit of code has to deal with that

$n88*+48*o\        Output a space, and prepare to output the first number we read in during the previous loop
          \        Loop round to the left end of this line
$n                 Output the value of the letters part as a number
  88*+             Add the 64 we subtracted from the first number
      48*o         Output a space
          \        Enter the next loop

This loop starts by outputting a character which will either be the 1st character read in by the first loop, or the character read in by the previous iteration of this loop.

oi:0(?;   >        Output the numbers part, by just echoing it
          >        Loop round to the start of the line
o                  Output the character
 i                 Read in the next character
  :0(?;            If the value read in was less than 0, terminate

Sasha

Posted 2017-08-16T00:21:44.073

Reputation: 431

1

Lua, 127 Bytes

Some nice string manipulations going there, I'm using some function that are usually never used while golfing in lua :D. The best way to golf this would be to find an other way to iterate over the column part of the input while being able to retain the position of each letter. I didn't ^^'.

Try it online!

I=...l=I:gsub("%d",""):reverse()r=0
for i=1,#l
do
r=r+(l:sub(i,i):byte()-64)*math.pow(26,i-1)end
print(r.." "..I:gsub("%a",""))

Explanation

I=...                       -- shorthand for the input
l=I:gsub("%d","")           -- shorthand for the column part
   :reverse()               -- letters are put in reverse order to calculate their weight
r=0                         -- column number
for i=1,#l                  -- iterate over the letters of the input
do
  r=r+                      -- add to the column number
      (l:sub(i,i):byte()-64)-- the byte value of the current letter minus 64 (A=1 this way)
      *math.pow(26,i-1)     -- then apply its weight in base 26
end
print(r                     -- output the column number
        .." "               -- a space
        ..I:gsub("%a",""))  -- and the row number

Katenkyo

Posted 2017-08-16T00:21:44.073

Reputation: 2 857