Codeforces: B. Spreadsheets


The problem is from codeforces: http://www.codeforces.com/problemset/problem/1/B

1B Codeforces: B. Spreadsheets

The implementation may not be so easy without Regual Expressions. The core idea is to provide conversion between base 10 and base 26. For example,

BC16 = 5510

The extraction of number(s) from string is the basic of the implementation. Using Python, but close to raw implementation without in [Pythonic] way, can be converted easily to other programming languages. The following implementation is easy to understand.

#!/usr/bin/env python
# https://helloacm.com

from sys import stdin

n = int(stdin.readline())

def convert1(row, col):
    s = ""
    while col:
        m = (col - 1) % 26
        col = (col - 1) / 26
        s = chr(65 + m) + s
    return s + str(row)

def convert2(s):
    r = 0
    for i in s:
        r = r * 26 + ord(i) - 64
    return r

# check which type
def chk(s):
    if s[0] == 'R' and s[1].isdigit():
        i = 2
        while i < len(s):
            if s[i] == 'C':
                return True
            i += 1
    return False

# extract numbers
def ex(s):
    rr = []
    r = 0
    i = 0
    while i < len(s):
        if not s[i].isdigit():
            i += 1
        else:
            break

    while i < len(s):
        if s[i].isdigit():
            r = r * 10 + ord(s[i]) - 48
            i += 1
        else:
            break
    rr.append(r)
    
    if i == len(s):
        return rr

    while i < len(s):
        if not s[i].isdigit():
            i += 1
        else:
            break    
    r = 0
    while i < len(s):
        if s[i].isdigit():
            r = r * 10 + ord(s[i]) - 48
            i += 1
        else:
            break
    rr.append(r)
    return rr
        
for i in xrange(n):
    s = stdin.readline()
    if chk(s):
        num = ex(s)
        print convert1(num[0], num[1])        
    else:
        i = 0
        while i < len(s):
            if s[i].isdigit():
                break
            else:
                i += 1
        print 'R' + s[i:].strip() + 'C' + str(convert2(s[:i])) 

The string handling part in above code does not look good and other shorter implementations are based on Regular expressions.

import re

f = lambda x : 26 ** x
for i in range(input()):
	s = raw_input()
	p = re.match('R(\d+)C(\d+)', s)
	if p:
		c = int(p.group(2))
		r = p.group(1)
		while c:
			r = chr(ord('A') + (c - 1) % 26) + r
			c = (c - 1) / 26
	else:
		p = re.match('(\D+)(\d+)', s)
		r = 'R' + p.group(2) + 'C'
		t = 0
		for x in p.group(1):
			t = t * 26 + ord(x) - ord('A') + 1
		r += str(t)
	print r

Or

n=input()
s=map(raw_input, ['']*n)

for i in s:
    r=''
    c = i.find('C')
    if c != -1 and i[c language="-1"][/c]<'A' and c >1:
        n=int(i[c language="+1:"][/c])
        while n: r=chr(ord('A') + (n-1)%26)+r; n=(n-1)/26 
        r+=i[1:c]
    else:
        j=0
        n=0
        while i[j] > '9':n=n*26+(ord(i[j])-ord('A')+1);j+=1
        r='R'+i[j:]+'C'+str(n) 
    print r

The alternative solution is:

m = {}
for k in range(26):
    m[chr(65+k)] = 1+k

for abcdd in range(int(raw_input())):
    a = raw_input()
    for k in range(len(a)):
        if a[k].isdigit():
            a, b = a[:k], a[k:]
            break
    if b.isdigit():
        n = 0
        for k in a:
            n = n * 26 + m[k]
        print "R" + b + "C" + str(n)
    else:
        c, b = b.split("C")
        a = "";
        b = int(b)
        while b:
            a = chr(65+(b-1)%26) + a
            b = int((b-1) / 26)
        print a + c

–EOF (The Ultimate Computing & Technology Blog) —

625 words
Last Post: Proof without Words
Next Post: Introduction to 0/1 Knapsack Problem

The Permanent URL is: Codeforces: B. Spreadsheets (AMP Version)

Leave a Reply