Spiral Array 퀴즈에 이어서 코드점수가 상금으로 주어지는 두번째 퀴즈입니다.
이번에는 답변을 주신 분들 중 추천수가 제일 많은 분의 답변을 채택할 예정입니다.
여러분들의 많은 투표 부탁드립니다!!
기한은 1월 말 2월 14일까지로 하겠습니다. ^^
현재 파이썬, 델파이, C, Lua, Ruby, C++, PHP, 파스칼, Perl, Common Lisp, Java 코드가 등장했네요..
여러 다양한 많은 언어의 참여를 기대합니다.
자 문제입니다:
LCD Display
한 친구가 방금 새 컴퓨터를 샀다. 그 친구가 지금까지 샀던 가장 강력한 컴퓨터는 공학용 전자 계산기였다. 그런데 그 친구는 새 컴퓨터의 모니터보다 공학용 계산기에 있는 LCD 디스플레이가 더 좋다며 크게 실망하고 말았다. 그 친구를 만족시킬 수 있도록 숫자를 LCD 디스플레이 방식으로 출력하는 프로그램을 만들어보자.
입력
입력 파일은 여러 줄로 구성되며 표시될 각각의 숫자마다 한 줄씩 입력된다. 각 줄에는 s와 n이라는 두개의 정수가 들어있으며 n은 출력될 숫자( 0<= n <= 99,999,999 ), s는 숫자를 표시하는 크기( 1<= s < 10 )를 의미한다. 0 이 두 개 입력된 줄이 있으면 입력이 종료되며 그 줄은 처리되지 않는다.
출력
입력 파일에서 지정한 숫자를 수평 방향은 '-' 기호를, 수직 방향은 '|'를 이용해서 LCD 디스플레이 형태로 출력한다. 각 숫자는 정확하게 s+2개의 열, 2s+3개의 행으로 구성된다. 마지막 숫자를 포함한 모든 숫자를 이루는 공백을 스페이스로 채워야 한다. 두 개의 숫자 사이에는 정확하게 한 열의 공백이 있어야 한다.
각 숫자 다음에는 빈 줄을 한 줄 출력한다. 밑에 있는 출력 예에 각 숫자를 출력하는 방식이 나와있다.
예
입력 예
2 12345
3 67890
0 0
출력 예
-- -- --
| | | | | |
| | | | | |
-- -- -- --
| | | | |
| | | | |
-- -- --
--- --- --- --- ---
| | | | | | | |
| | | | | | | |
| | | | | | | |
--- --- ---
| | | | | | | |
| | | | | | | |
| | | | | | | |
--- --- --- ---
저도 가입기념으로 풀이 하나 달아봅니다.
제 밥벌이인 "델파이"로 만들어 봤습니다.
program CodeJob;
{$APPTYPE CONSOLE}
type
TDigitH = array [0..3-1] of Char;
TDigitHType = (dhN, dhH, dhVA, dhVL, dhVR);
TDigit = array [0..5-1] of TDigitHType;
TDigitChar = '0' .. '9';
const
DigitHTypes: array [TDigitHType] of TDigitH = (
(' ',' ',' '),(' ','-',' '),('|',' ','|'),('|',' ',' '),(' ',' ','|')
);
DigitArray: array [TDigitChar] of TDigit = (
// Digit 0
(dhH, dhVA, dhN, dhVA, dhH),
// Digit 1
(dhN, dhVR, dhN, dhVR, dhN),
// Digit 2
(dhH, dhVR, dhH, dhVL, dhH),
// Digit 3
(dhH, dhVR, dhH, dhVR, dhH),
// Digit 4
(dhN, dhVA, dhH, dhVR, dhN),
// Digit 5
(dhH, dhVL, dhH, dhVR, dhH),
// Digit 6
(dhH, dhVL, dhH, dhVA, dhH),
// Digit 7
(dhH, dhVR, dhN, dhVR, dhN),
// Digit 8
(dhH, dhVA, dhH, dhVA, dhH),
// Digit 9
(dhH, dhVA, dhH, dhVR, dhH)
);
procedure printDigitVLine(aDigit: TDigit; aWidth, aHeight, aVLine: Integer);
var
k,
ii, ij: Integer;
begin
if (aVLine = 0) then ii := 0
else
if (aVLine = aHeight-1) then ii := 4
else
if (aVLine = aHeight div 2) then ii := 2
else
if (aVLine < aHeight div 2) then ii := 1
else ii := 3;
k := 0;
while k < aWidth do
begin
if (k = 0) then ij := 0 else if (k = aWidth-1) then ij := 2 else ij := 1;
Write(DigitHTypes[aDigit[ii]][ij]);
Inc(k);
end;
end;
procedure printDigitStr(const aDigitStr: String; aWidth, aHeight: Integer); overload;
var
i, j: Integer;
begin
for i := 0 to aHeight - 1 do
begin
for j := 1 to Length(aDigitStr) do
begin
printDigitVLine(DigitArray[aDigitStr[j]], aWidth, aHeight, i);
Write(' ');
end;
WriteLn('');
end;
end;
procedure printDigitStr(const aDigitStr: String; aScale: Integer); overload;
begin
if aScale < 1 then Exit;
printDigitStr(aDigitStr, aScale + 2, aScale * 2 + 3);
end;
function StrToIntDef(const S: string; Default: Integer): Integer;
var
E: Integer;
begin
Val(S, Result, E);
if E <> 0 then Result := Default;
end;
procedure FileProc(const aFileName: String);
var
F: TextFile;
S: String;
begin
AssignFile(F, aFileName);
Reset(F);
while not EOF(F) do
begin
Readln(F, S);
if S = '0 0' then Break;
printDigitStr(PChar(@S[3]), StrToIntDef(S[1], 0));
WriteLn('');
end;
CloseFile(F);
end;
procedure AppProc;
var
s: String;
begin
if ParamCount > 0 then
FileProc(ParamStr(1))
else
WriteLn('No input file.'#13#10);
Write('Press any key...');
readln(s);
end;
begin
AppProc;
end.
터보델파이로 빌드하면 22k 나오네요.
원본 텍스트 파일이 다음과 같을 때
input.txt
"CodeJob input.txt" 라고 실행시킨 출력결과는 다음과 같습니다.
좋은 사이트 만들어주셔서 감사합니다. 자주 자주 놀러올께요~ ^^;;
ps. 중복된 정보를 조금 털어내서 실행파일 크기를 1k 정도 더 줄여봤습니다.
좀 더 최적화의 여지가 있겠지만... 제 능력은 여기까지 같아요~ ^^;
(수정 전 원본은 http://oranke.tistory.com/190 에)
Ruby 로 놀다 갑니다..
$img = [ "TBtLbRbLtR", "tRbR", "TMBtRbL", "TBMtRbR", "tLtRMbR",
"TBMtLbR", "MBTtLbRbL", "TtRbR", "TBMtLtRbLbR", "TBMtRbRtL" ]
def get_number_string( scale, num )
def get_c( c, flag, char )
$img[c.to_i].include?(flag) ? char : " "
end
r = ""
num.each_char { |c| r += " #{get_c(c, 'T', '-')*scale} " }
r += "\n"
t = ""
num.each_char { |c| t += "#{get_c(c, 'tL', '|')+' '*scale+get_c(c, 'tR', '|')+' '}" }
r += ( t + "\n" ) * scale
num.each_char { |c| r += " #{get_c(c, 'M', '-')*scale} " }
r += "\n"
t = ""
num.each_char { |c| t += "#{get_c(c, 'bL', '|')+' '*scale+get_c(c, 'bR', '|')+' '}" }
r += ( t + "\n" ) * scale
num.each_char { |c| r += " #{get_c(c, 'B', '-')*scale} " }
r += "\n\n"
end
while true do
n1, n2 = STDIN.readline.chomp.split( " " )
break if n1.to_i < 1 or n1.to_i >= 10 or n2.to_i < 0 or n2.to_i > 99999999
puts get_number_string( n1.to_i, n2 )
end

ps. 여기선 루비 스트링 하이라이팅이 제대로 안되는군요. 흠 ;
Ruby (버전 1.8.7) 로 해봤습니다. 짧게 줄이다보니 아라크넹님과 알고리즘이 비슷해졌네요. (..하지만 약간 다름)
공백 포함 141바이트입니다.
$_=[28728,609961108,14680127,340862356,14708792].map{|x|~/ /
$'.gsub(/./){k=' - | | '[7&x>>$&.hex*3,4]
k[1,1]*=S=$_.hex
k}.*x%7<1?1:S},$/
압축하면 131바이트가 됩니다.
$_="8p\000\000\224D[$?\000\340\000\224%Q\0248p\340\000".unpack('L*').map{|x|~/ /
$'.gsub(/./){k=' - | | '[7&x>>$&.hex*3,4]
k[1,1]*=S=$_.hex
k}.*x%7<1?1:S},$/

사용법

common lisp 으로 만들어 봤습니다.
(defparameter *number-def*
(make-array 10 :initial-contents
'((H LR nil LR H)
(nil R nil R nil)
(H R H L H)
(H R H R H)
(nil LR H R nil)
(H L H R H)
(H L H LR H)
(H R nil R nil)
(H LR H LR H)
(H LR H R nil))))
(defun transpose (x)
(apply #'mapcar (cons #'list x)))
(defun make-print-data (lst scale)
(flet ((s (node)
(cond ((eq node 'H) (append '(nil) (make-list scale :initial-element 'hipen) '(nil)))
((eq node 'LR) (append '(bar) (make-list scale) '(bar)))
((eq node 'L) (append '(bar) (make-list (1+ scale))))
((eq node 'R) (append (make-list (1+ scale)) '(bar)))
(t (make-list (+ scale 2))))))
(loop for line in (mapcar (lambda (x)
(mapcar #'s x))
lst)
for i from 0
collect line
when (equal (rem i 2) 1)
append (loop repeat (1- scale) collect line))))
(defun print-symbol (output ss colon-p at-p)
(princ (coerce
(mapcar (lambda (x)
(cond ((eq x 'hipen) #\-)
((eq x 'bar) #\|)
(t #\space)))
ss)
'string)
output))
(defun print-line (lst)
(format t "~{~{~/print-symbol/ ~}~%~}~%" lst))
(defun process-line (line)
(multiple-value-bind (scale pos) (read-from-string line)
(let ((data (map 'list
(lambda (x)
(- (char-code x) (char-code #\0)))
(subseq line pos))))
(print-line (make-print-data (transpose (mapcar (lambda (x)
(aref *number-def* x))
data))
scale)))))
(defun read-loop (is)
(do ((line (read-line is nil)
(read-line is nil)))
((or (null line)
(equal (string-trim '(#\space #\tab #\newline) line) "0 0"))
nil)
(process-line line)))
(defun main ()
(fresh-line)
(read-loop *standard-input*))
mac 에서 clozure lisp 으로 실행시킨 결과입니다.

자바 좀더 짧은 버전입니다.
import java.io.*;
public class Main {
public static int nFlags[] = {0x77, 0x12, 0x5D, 0x5B, 0x3A, 0x6B, 0x6F, 0x52, 0x7F, 0x7A, 0x00};
public static void main(String[] args) throws IOException {
BufferedReader reader = new BufferedReader(new FileReader("C:\\test.txt"));
String line;
while((line = reader.readLine()) != null) {
String[] arr = line.split(" ");
int[] narr = new int[arr[1].length()];
for(int i=0; i<arr[1].length(); i++)
narr[i] = arr[1].charAt(i) - 0x30;
printNumbers(narr, Integer.parseInt(arr[0].trim()));
}
}
public static void printNumbers(int[] num, int pc) {
for(int i=1; i<=5; i++) {
if(i%2==0)
for(int k=0; k<pc; k++) {
for(int j=0; j<num.length; j++) {
System.out.print(((nFlags[num[j]] >> (int)((5-i)*1.5)+1)&0x01)==1?'|':' ');
for(int l=0; l<pc; l++)
System.out.print(' ');
System.out.print((((nFlags[num[j]] >> (int)((5-i)*1.5))&0x01)==1?'|':' ')+" ");
}
System.out.println();
}
else {
for(int j=0; j<num.length; j++) {
System.out.print(' ');
for(int l=0; l<pc; l++)
System.out.print(((nFlags[num[j]] >> (int)((5-i)*1.5))&0x01)==1?'-':' ');
System.out.print(" ");
}
System.out.println();
}
}
}
}
스크립트 계열 언어들 대단하군요. 골프 기교 처음봅니다.
누군가가 자바도 골프에 가까운 기교를 한번 구현해서 올려보길 기대해봅니다.
저도 가입기념으로 복잡하지만, 제 스타일 대로.. ㅡ.ㅡ;
program Sample;
{$APPTYPE CONSOLE}
{$R *.res}
uses
System.SysUtils,
TextCanvas in 'TextCanvas.pas',
DigitFont in 'DigitFont.pas';
var
DigitFont : TDigitFont;
begin
DigitFont := TDigitFont.Create;
try
DigitFont.FontSize := 1;
DigitFont.WriteDigit('01234');
WriteLn;
DigitFont.FontSize := 2;
DigitFont.WriteDigit('56789');
finally
DigitFont.Free;
end;
Write('Press any key...');
ReadLn;
end.
문제대로 파일을 읽고 등등은 생략 ^^;
문제의 핵심을 폰트 크기와 숫자를 LED 디스플레이로 표시하는 것으로 압축하고,
거기에 해당하는 인터페이스를 가진 클래스 제작.
그리고 실행 결과
TDigitFont 클래스의 중요 소스
procedure TDigitFont.WriteDigit(Digit:string);
const
_FontWidth = 3;
_FontHeight = 5;
var
sFontData : string;
Loop: Integer;
begin
FCanvas.Width := Length(Digit) * (FontSize + 1) * _FontWidth;
FCanvas.Height := FontSize * _FontHeight;
FCanvas.Clear;
for Loop := 0 to Length(Digit)-1 do begin
// 현재 폰트를 찍을 위치로
FCanvas.MoveTo(Loop * (FontSize + 1) * _FontWidth, 0);
// 현재 폰트의 벡터 정보 가져오기
sFontData := _DigitFontData[Ord(Digit[Loop+1]) - Ord('0')];
draw_Digit(sFontData);
end;
FCanvas.Draw;
end;
procedure TDigitFont.draw_Digit(FontData: string);
var
Loop : Integer;
begin
for Loop := 1 to Length(FontData) do begin
case FontData[Loop] of
'l': FCanvas.MoveLeft;
'r': FCanvas.MoveRight;
'd': FCanvas.MoveDown;
'u': FCanvas.MoveUp;
'<': FCanvas.MoveLeft(FontSize);
'>': FCanvas.MoveRight(FontSize);
'.': FCanvas.MoveDown(FontSize);
'^': FCanvas.MoveUp(FontSize);
'L': FCanvas.LineLeft(FontSize);
'R': FCanvas.LineRight(FontSize);
'D': FCanvas.LineDown(FontSize);
'U': FCanvas.LineUp(FontSize);
end;
end;
end;
각 폰트의 벡터 정보를 토대로 폰트를 그린다.
벡터 정보는 아래와 같다.
lrdu : 한 칸 이동 (각각 Left, Right, Down, Up)
<>,^ : 폰트 크기 만큼 이동 (각각 Left, Right, Down, Up)
LRDU : 폰트 크기 만큼 직선 그리기 (각각 Left, Right, Down, Up)
const
_DigitFontData : array [0..9] of string = (
'dDdDrRuUuUlL', // 0
'rrdDdD', // 1
'rRdDlLdDrR', // 2
'rRdDdDlL^urR', // 3
'dDrR^DdD', // 4
'rR<ldDrRdDlL', // 5
'rLdDrRdDlLuU', // 6
'rRdDdD', // 7
'rRdDlLdDrRuUl<uU', // 8
'd.rLuUrRdDdDlL' // 9
);
위에서 사용되는 TTextCanvas 클래스의 인터페이스 (FCanvas)
type
TTextCanvas = class
private
public
procedure Clear;
procedure MoveTo(X,Y:integer);
procedure MoveLeft(Count:integer = 1);
procedure MoveRight(Count:integer = 1);
procedure MoveDown(Count:integer = 1);
procedure MoveUp(Count:integer = 1);
procedure LineLeft(Count:integer = 1);
procedure LineRight(Count:integer = 1);
procedure LineDown(Count:integer = 1);
procedure LineUp(Count:integer = 1);
procedure Draw;
property X : integer;
property Y : integer;
property Width : integer;
property Height : integer;
end;
실제 코드는 http://ryulib.tistory.com/181
다양한 언어로 던지라고 하시니, 스크립트 중 제가 제일 좋아라하는 루아도 하나 투척합니다~~ ^^;;
내용은 델파이나 씨로 짠 것과 거의 동일한데...
루아의 콘솔 출력함수인 print() 가 줄단위 출력만 되는 바람에 약간 수정되었네요.
CodeJob.lua
dhN = 1; dhH = 2; dhVA = 3; dhVL = 4; dhVR = 5;
DigitHTypes = {
{' ',' ',' '}, {' ','-',' '}, {'|',' ','|'},{'|',' ',' '}, {' ',' ','|'}
}
DigitArray = {
{dhH, dhVA, dhN, dhVA, dhH}, {dhN, dhVR, dhN, dhVR, dhN},
{dhH, dhVR, dhH, dhVL, dhH}, {dhH, dhVR, dhH, dhVR, dhH},
{dhN, dhVA, dhH, dhVR, dhN}, {dhH, dhVL, dhH, dhVR, dhH},
{dhH, dhVL, dhH, dhVA, dhH}, {dhH, dhVR, dhN, dhVR, dhN},
{dhH, dhVA, dhH, dhVA, dhH}, {dhH, dhVA, dhH, dhVR, dhH}
}
function buildDigitVLine(aDigit, aWidth, aHeight, aVLine)
local k = 0;
local ii, ij;
local halfHeight = math.floor(aHeight/2);
if (aVLine == 0) then ii = 0
elseif (aVLine == aHeight-1) then ii = 4
elseif (aVLine == halfHeight) then ii = 2
elseif (aVLine < halfHeight) then ii = 1
else ii = 3 end;
local str = '';
while (k < aWidth) do
if (k == 0) then ij = 0
elseif (k == aWidth-1) then ij = 2
else ij = 1 end;
str = str .. DigitHTypes[aDigit[ii+1]][ij+1];
k = k + 1;
end;
return str;
end;
function printDigitStr(aDigitStr, aScale)
if (aScale < 1) then return end;
local i, j;
local Width = aScale + 2;
local Height = aScale * 2 + 3;
for i=0, Height-1, 1 do
local outStr = '';
for j=1, string.len(aDigitStr), 1 do
outStr =
outStr ..
buildDigitVLine(
DigitArray[string.byte(aDigitStr,j) - 48 + 1],
Width, Height, i
) .. ' ';
end;
print(outStr);
end;
end;
fh = io.open("input.txt", "r");
while true do
local Scale = fh:read("*n");
local Value = fh:read("*n");
if not Scale then break end;
if (Scale == 0 and Value == 0) then break end;
printDigitStr(tostring(Value), Scale);
end;
fh:close();
CodeJob.lua 파일과 input.txt 를 한 곳에 몰아넣고 루아콘솔에서 dofile("CodeJob") 로 실행한 결과는 다음과 같습니다.

개인적으로는 PHP코드가 올라오면 공부가 많이 될 듯한 소망이 있는데~~
새해 복 많이 받으시고 앞으로도 재미난 문제 많이 내 주세요~~ ^^;;
오랑캐꽃님의 알고리즘을 파이썬으로 바꾸어 보았어요.
파이썬 버전 : 오랑캐꽃님의 알고리즘
import math
dhN = 1; dhH = 2; dhVA = 3; dhVL = 4; dhVR = 5;
DigitHTypes = (
(' ',' ',' '), (' ','-',' '), ('|',' ','|'),('|',' ',' '), (' ',' ','|')
)
DigitArray = (
(dhH, dhVA, dhN, dhVA, dhH), (dhN, dhVR, dhN, dhVR, dhN),
(dhH, dhVR, dhH, dhVL, dhH), (dhH, dhVR, dhH, dhVR, dhH),
(dhN, dhVA, dhH, dhVR, dhN), (dhH, dhVL, dhH, dhVR, dhH),
(dhH, dhVL, dhH, dhVA, dhH), (dhH, dhVR, dhN, dhVR, dhN),
(dhH, dhVA, dhH, dhVA, dhH), (dhH, dhVA, dhH, dhVR, dhH)
)
def printDigitVLine(aDigit, aWidth, aHeight, aVLine):
k = 0
halfHeight = math.floor(aHeight/2)
if aVLine == 0 : ii = 0
elif aVLine == aHeight-1: ii = 4
elif aVLine == halfHeight: ii = 2
elif aVLine < halfHeight: ii = 1
else: ii = 3
result = []
while k < aWidth:
if k == 0: ij = 0
elif k == aWidth-1: ij = 2
else: ij = 1
result.append(DigitHTypes[aDigit[ii]-1][ij])
k += 1
print "".join(result),
def printDigitStr(aDigitStr, aScale):
if aScale < 1: return
Width = aScale + 2
Height = aScale * 2 + 3
for i in range(0, Height):
for j in range(0, len(aDigitStr)):
printDigitVLine(DigitArray[int(aDigitStr[j])], Width, Height, i)
print "\n",
for line in open("input.txt"):
if not line: break
Scale, Value = line.split()
if Scale == "0" and Value == "0": break
printDigitStr(Value, int(Scale))
Testors님의 Ruby를 C++로 바꿔서 올려봅니다.
아무래도 Ruby처럼 깔끔하지는 않네요;;
#include <stdio.h>
#include <tchar.h>
#include <string>
#include <vector>
#include <algorithm>
#include <iostream>
#include <iterator>
#include <conio.h>
char img[] = { 0x77, 0x24, 0x5d, 0x6d, 0x2e, 0x6b, 0x7b, 0x27, 0x7f, 0x6f };
char get_c( int num, int flag, char match )
{
return ( ( img[num] & flag) == flag ) ? match : ' ';
}
std::string horz( int scale, const std::vector <int>& nums, int flag )
{
std::string str;
std::for_each( nums.begin(), nums.end(), [&]( char num )
{
str += ' ';
for ( int i = 0; i < scale; ++i )
str += get_c( num, flag, '-' );
str += ' ';
}
);
str += '\n';
return str;
}
std::string vert( int scale, const std::vector <int>& nums, int flagl, int flagr )
{
std::string str, vert;
std::for_each( nums.begin(), nums.end(), [&]( char num )
{
vert += get_c( num, flagl, '|' );
for ( int i = 0; i < scale; ++i )
vert += ' ';
vert += get_c( num, flagr, '|' );
}
);
for ( int i = 0; i < scale; ++i )
str += vert + '\n';
return str;
}
std::string get_num_string( int scale, const std::vector <int>& nums )
{
std::string str;
str += horz( scale, nums, 0x01 );
str += vert( scale, nums, 0x02, 0x04 );
str += horz( scale, nums, 0x08 );
str += vert( scale, nums, 0x10, 0x20 );
str += horz( scale, nums, 0x40 );
str += "\n\n";
return str;
}
int _tmain(int argc, _TCHAR* argv[])
{
int s;
std::string num_str;
while ( true )
{
std::cin >> s;
std::cin >> num_str;
if ( s == 0 && num_str[0] == '0' )
break;
std::vector <int> nums;
std::transform( num_str.begin(), num_str.end(), std::back_inserter( nums ), [] ( char c ) { return c - '1' + 1; } );
std::cout << get_num_string( s, nums );
}
return 0;
}
<?
/*
---0
|1 |2
---3
|4 |5
---6
*/
// number-index array
$number_a = array(
array(1, 1, 1, 0, 1, 1, 1), // 0
array(0, 0, 1, 0, 0, 1, 0), // 1
array(1, 0, 1, 1, 1, 0, 1), // 2
array(1, 0, 1, 1, 0, 1, 1), // 3
array(0, 1, 1, 1, 0, 1, 0), // 4
array(1, 1, 0, 1, 0, 1, 1), // 5
array(1, 1, 0, 1, 1, 1, 1), // 6
array(1, 0, 1, 0, 0, 1, 0), // 7
array(1, 1, 1, 1, 1, 1, 1), // 8
array(1, 1, 1, 1, 0, 1, 1) // 9
);
$inputfile = file('input.txt');
foreach ($inputfile as $line) {
$l_e = explode(' ', $line);
if($l_e[0]==0 && $l_e[1]==0) {
break;
}
$s_length = $l_e[0];
$number_string = $l_e[1];
$number_string_count = strlen($number_string);
$line_s = array();
for($j=0;$j<$number_string_count;$j++) {
$n_a = $number_a[$number_string[$j]];
if($n_a)foreach($n_a as $ln => $n) {
if($ln==0 || $ln==3 || $ln==6) {
$line_str = '-';
} else {
$line_str = '|';
}
if($n!=1) {
$line_str = ' ';
}
// index 값
if($ln==0 || $ln==1) {
$index = $ln;
} else if($ln==3 || $ln==4) {
$index = $ln+$s_length;
} else if($ln==2) {
$index = $ln-1;
} else if($ln==5) {
$index = $ln-1+$s_length;
} else if($ln==6) {
$index = ($ln-1)+($s_length*2);
} else {
}
switch($ln) {
case 0 :
case 3 :
case 6 :
$line_s[$index].= ' '.str_repeat($line_str, $s_length).' ';
break;
case 1 :
case 4 :
case 2 :
case 5 :
for($i=$index;$i<$index+$s_length;$i++) {
if($ln==2 || $ln==5) {
$l_str = ' ';
} else {
$l_str = '';
}
$line_s[$i].= $line_str.$l_str;
if($ln==1 || $ln==4) {
$line_s[$i].= str_repeat(' ', $s_length);
}
}
break;
default :
break;
}
}
}
foreach($line_s as $ln => $n) {
echo $n."\n";
}
echo "\n";
}
?>

오류 검사부분은 완전히 배제했습니다. >.<
평소에 생각해보지 않았는데 은근히 힘드네요.
함수 배제하고 for 문을 남발한게 좀 그렇긴 하지만 좋은 공부 된것 같습니다. ㄳ
오랜만에 파이썬을 써봐서 그다지 적절하지 못한 코드가 나왔습니다. 요점은 함수적으로 작성하려고 노력했다는 것이지만 나온 결과는 개떡 같은 코드가 되었습니다. 혹시나 파이썬을 접하지 못한 분들께 오해를 불러올까봐 노파심에 한 마디 해야 할 것 같은데, 대부분의 파이썬 코드는 훨씬 깨끗하고 이해하기 쉬운 코드랍니다.
루비 같은 언어였으면 코드 골프질을 하는 것도 재미있었을 것 같군요.
수정: 간만에 쓰니까 존재를 까먹은 함수들이 많네요. 좀 더 정상적인 코드로 수정을 해보았습니다.
def digit(size, number):
def h(c): return ' ' + c * size + ' \n'
def v(l, r): return (l + ' ' * size + r + '\n') * size
def c(bit): return '-||-||-'[bit] if [119, 18, 93, 91, 58, 107, 111, 82, 127, 123][number] & 2**bit else ' '
return h(c(6)) + v(c(5), c(4)) + h(c(3)) + v(c(2), c(1)) + h(c(0))
def digits(size, input):
return '\n'.join(map(lambda x: ' '.join(x),
zip(*map(lambda n: digit(size, n).split('\n')[:-1], input))
))+'\n' if size > 0 else ''
print(digits(2, [1, 2, 3, 4, 5]))
print(digits(3, [6, 7, 8, 9, 0]))
print(digits(0, [0]))
사람들이 좋아하는 코드를 짤 능력은 없지만, 골프 코드를 모두 즐겨 보았으면 해서 이 글타래에서 가장 인기 있어 보이는 델파이로 아라크넹 님의 코드를 번역해 보았습니다. (루비 코드는 도무지 해독이 안됩니다!)
가능한 원래 코드의 의도를 살리려고 하였고 언어의 한계로 직역이 불가능한 부분은 흐름을 해치지 않도록 손봤습니다.
먼저 번역하기 위해 수정한 파이썬 코드입니다.
p=1
while p:
p,q=raw_input().split();p=int(p)
if p:
for x in[28728]+[240145116382356]*p+[481051017279]+[240144847283604]*p+[246298135523384,-1]: # 7-segment row magic keys
sc = ' - | | ' # 7-segment column
for j in q:
di = (x >> (int(j, 16) * 3)) &7
print sc[di+1] + sc[di+2]*p + sc[di+3] + ' ',
print ''
리스트 제너레이터와 문자열 조인을 떼고 나니 코드가 눈에 조금 들어오기 시작합니다.
서브스트링은 파이썬과 달리 쉽지 않으니 인덱스로 대체했습니다.
리스트 곱은 상황에 따라 다른 기교로 처리해야 할 것 같으므로 일단 두었습니다.
공백문자 출력이 원본과 다르겠지만 눈에는 똑같이 보이므로 따로 처리하지 않습니다.
번역한 파스칼 코드입니다. 윈도를 사용하지 않기 때문에 불가피하게 프리파스칼을 쓰게 되었습니다.
for in 루프를 지원하는 델파이에서 아마 문제 없이 컴파일 되리라 생각합니다.
type tx = Array[0..1] of LongInt;
const
xx: Array[1..6] of tx = ((28728, 1), (609961108, 0), (14680127, 1), (340862356, 0), (14708792, 1), (-1, 1)); // magic keys for each row of 7-segment
sc = ' - | | '; // 7-segment strings
var
i,ii,di,p:Integer;
q:String;
j:char;
x:tx;
begin
p := 1;
while p > 0 do begin
readln(p, j, q); // dump out space j
if p > 0 then begin
xx[2][1] := p; xx[4][1] := p; // set row length ( list*p in python )
for x in xx do for i := 1 to x[1] do begin // for x in ... loop
for j in q do begin // for j in q generator
di := x[0] shr ((ord(j) - 48) * 3) and 7;
// verbose print for ' '.join
write(sc[di+1]);
for ii := 1 to p do write(sc[di+2]);
write(sc[di+3], ' ')
end;
writeln
end
end
end
end.
변수를 최대한 파이썬 코드와 일치하게 맞췄습니다.
for x in 루프의 리스트 곱을 흉내내기 위해 루프 하나를 더 도입하고 x를 배열로 만든 것 외에는 수정한 파이썬 코드를 거의 그대로 옮겼습니다.
해독은 각자 즐길 수 있는 재미라고 생각하여 언어 상의 차이 외엔 전혀 손대지 않으려고 노력하였습니다.
실행하면...

원래 코드처럼 나옵니다
작업 후 덤으로, 저는 골퍼는 아니지만 원본이 골프였는 만큼 나름 줄이려고 노력은 해보았습니다.
const y:Array[1..6]of Int64=(28728,609961108,$e0003f,340862356,$e07038,-1);S=' - | | ';var g,i,k,d,p:Word;q:String;j:char; begin p:=1;while p>0do begin readln(p,j,q);if p>0then begin for g:=1to 6do begin i:=1;if g in[2,4]then i:=p;for i:=1to i do begin for j in q do begin d:=y[g]shr(ord(j)*3-144)and 7;write(S[d+1]);for k:=1to p do write(S[d+2]);write(S[d+3],' ') end;writeln end end end end end.
그래도 400바이트입니다. 골프 기교와 언어에 대한 이해가 모두 부족해서겠지만 더 이상은 못줄이겠네요.
파스칼로 파이썬 코드 두배 정도면 선방한 셈이라 생각합니다 :)
프리파스칼 확장을 이용하면 2바이트 더 줄일 수 있습니다.
const y:Array[1..6]of Int64=(28728,609961108,$e0003f,340862356,$e07038,-1);S=' - | | ';var g,i,k,d,p:Word;q,b:String;j:char; begin p:=1;while p>0do begin readln(p,j,q);if p>0then begin for g:=1to 6do begin i:=1;if g in[2,4]then i:=p;for i:=1to i do begin b:='';for j in q do begin d:=y[g]>>(ord(j)*3-144)and 7;b+=S[d+1];for k:=1to p do b+=S[d+2];b+=S[d+3]+' ' end;writeln(b) end end end end end.
덕분에 재미있었습니다 감사합니다.
안드로이드 펍에서 자바 누가좀 올려줬으면 좋겠다는 분이 계셔서 한번 만들어 봤습니다.
class 는 두개로 나뉘어 졌고, main method 에서 실행하는 코드가 몇줄 있습니다. 생각보다 길어졌네요.
1) 숫자를 뿌려주는 클래스 입니다.
public class Displayer
{
private static Displayer instance;
private static final String horizontal = "-";
private static final String vertical = "|";
private static final String space = " ";
private static final String new_line = "\r\n";
private static final boolean[] NUMBER_FORMAT_TOP = new boolean[] { true, false, true, true, false, true, true, true, true, true };
private static final boolean[] NUMBER_FORMAT_LEFT_TOP = new boolean[] { true, false, false, false, true, true, true, false, true, true };
private static final boolean[] NUMBER_FORMAT_RIGHT_TOP = new boolean[] { true, true, true, true, true, false, false, true, true, true };
private static final boolean[] NUMBER_FORMAT_DIVIDER = new boolean[] { false, false, true, true, true, true, true, false, true, true };
private static final boolean[] NUMBER_FORMAT_LEFT_BOTTOM = new boolean[] { true, false, true, false, false, false, true, false, true, false };
private static final boolean[] NUMBER_FORMAT_RIGHT_BOTTOM = new boolean[] { true, true, false, true, true, true, true, true, true, true };
private static final boolean[] NUMBER_FORMAT_BOTTOM = new boolean[] { true, false, true, true, false, true, true, false, true, true };
private Displayer()
{}
synchronized public static Displayer getInstance()
{
if (instance == null)
instance = new Displayer();
return instance;
}
private int size = 1;
private String number = "0";
public void init(int size, String number)
{
this.size = size;
this.number = number;
width = size + 2;
height = size * 2 + 3;
center = ((height - 1) / 2);
}
private int width, height, center;
public void drawNumbers()
{
if (size == 0 && number.equals("0"))
return;
System.out.print(new_line);
for (int i = 0; i < height; i++)
{
System.out.print(new_line);
for (int n = 0; n < number.length(); n++)
{
System.out.print(space);
int num = Integer.parseInt(number.substring(n, n + 1));
for (int j = 0; j < width; j++)
{
// 첫 줄
if (i == 0)
{
// 첫 칸과 마지막 칸
if (needSpace(j))
System.out.print(space);
else
{
if (NUMBER_FORMAT_TOP[num])
System.out.print(horizontal);
else
System.out.print(space);
}
}
// 마지막 줄
else if (i == (height - 1))
{
// 첫 칸과 마지막 칸
if (needSpace(j))
System.out.print(space);
else
{
if (NUMBER_FORMAT_BOTTOM[num])
System.out.print(horizontal);
else
System.out.print(space);
}
}
// 중간 디바이더
else if (i == center)
{
// 첫 칸과 마지막 칸
if (needSpace(j))
System.out.print(space);
else
{
if (NUMBER_FORMAT_DIVIDER[num])
System.out.print(horizontal);
else
System.out.print(space);
}
}
else
{
// 왼쪽
if (j == 0)
{
// 위
if (i < center)
{
if (NUMBER_FORMAT_LEFT_TOP[num])
System.out.print(vertical);
else
System.out.print(space);
}
// 아래
else
{
if (NUMBER_FORMAT_LEFT_BOTTOM[num])
System.out.print(vertical);
else
System.out.print(space);
}
}
// 오른쪽
else if (j == (width - 1))
{
// 위
if (i < center)
{
if (NUMBER_FORMAT_RIGHT_TOP[num])
System.out.print(vertical);
else
System.out.print(space);
}
// 아래
else
{
if (NUMBER_FORMAT_RIGHT_BOTTOM[num])
System.out.print(vertical);
else
System.out.print(space);
}
}
else
System.out.print(space);
}
}
}
}
}
private boolean needSpace(int j)
{
return (j == 0 || j == (width - 1));
}
}
2) 파일에서 숫자정보를 로드하는 class 입니다.
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
public class FileLoader
{
private static FileLoader instance;
private FileLoader()
{}
synchronized public static FileLoader getInstance()
{
if (instance == null)
instance = new FileLoader();
return instance;
}
File f;
ArrayList<Integer> sizes = new ArrayList<Integer>();
ArrayList<String> numbers = new ArrayList<String>();
public boolean loadFile(String fileName)
{
try
{
if (fileName.contains("\\") || fileName.contains("/"))
f = new File(fileName);
else
f = new File(".\\" + fileName);
FileInputStream fis = new FileInputStream(f);
InputStreamReader isr = new InputStreamReader(fis);
BufferedReader br = new BufferedReader(isr);
String s;
while ((s = br.readLine()) != null)
{
String[] line = s.split(",");
if (line != null && s.length() > 1)
{
sizes.add(Integer.parseInt(line[0].trim()));
numbers.add(line[1].trim());
}
}
if (sizes.size() <= 0)
{
System.out.println("sizes format error");
return false;
}
if (numbers.size() <= 0)
{
System.out.println("numbers format error");
return false;
}
if (sizes.get(sizes.size() - 1) != 0)
{
System.out.println("end of list not available");
return false;
}
if (!numbers.get(numbers.size() - 1).equals("0"))
{
System.out.println("end of list not available");
return false;
}
return true;
}
catch (Throwable e)
{
return false;
}
}
public ArrayList<Integer> getSize()
{
return sizes;
}
public ArrayList<String> getNumbers()
{
return numbers;
}
}
3) 두개의 class 를 이용해서 실행하는 코드입니다.
FileLoader loader = FileLoader.getInstance();
Displayer displayer = Displayer.getInstance();
if(loader.loadFile("number.txt"))
{
ArrayList<Integer> sizes = loader.getSize();
ArrayList<String> numbers = loader.getNumbers();
for(int i=0 ; i < sizes.size() ; i++)
{
displayer.init(sizes.get(i), numbers.get(i));
displayer.drawNumbers();
}
}
결과화면은 이렇습니다.
입력
2, 12345 3, 67890 4, 12345 0, 0
출력
-- -- --
| | | | | |
| | | | | |
-- -- -- --
| | | | |
| | | | |
-- -- --
--- --- --- --- ---
| | | | | | | |
| | | | | | | |
| | | | | | | |
--- --- ---
| | | | | | | |
| | | | | | | |
| | | | | | | |
--- --- --- ---
---- ---- ----
| | | | | |
| | | | | |
| | | | | |
| | | | | |
---- ---- ---- ----
| | | | |
| | | | |
| | | | |
| | | | |
---- ---- ----
감사합니다.
#변수 초기화
inputNumber = "123456789012345"
top = 0
bottom = 0
middle = 0
digit = [" # ", " # ","|# "," #|","|#|"]
#문자를 초기화
def initDigit():
digit[0] = " # "
digit[1] = " # "
digit[2] = "|# "
digit[3] = " #|"
digit[4] = "|#|"
#문자를 대입
def makeDigit(x):
linestr = ""
whitestr = ""
for i in range(x):
whitestr += " "
linestr += "-"
for i in range(len(digit)):
if( i == 1):
digit[i] = digit[i].replace('#',linestr)
else :
digit[i] = digit[i].replace('#',whitestr)
#기준 정하기 / 위 / 중간 / 아래
def setCriterion(x):
global top
global middle
global bottom
top = 1
middle = 2+x
bottom = 3+(x*2)
#문자를 LCD 타입으로 표시하기
def textToGraphic(x, line) :
#1
if(x == 1 and ((line == top) or (line == middle) or (line == bottom))) :
return digit[0]
if(x == 1 and ((line != top) or (line != middle) or (line != bottom))) :
return digit[3]
#2
if(x == 2 and ((line == top) or (line == middle) or (line == bottom))) :
return digit[1]
if(x == 2 and (top < line < middle)) :
return digit[3]
if(x == 2 and (middle < line < bottom)) :
return digit[2]
#3
if(x == 3 and ((line == top) or (line == middle) or (line == bottom))) :
return digit[1]
if(x == 3 and ((line != top) or (line != middle) or (line != bottom))) :
return digit[3]
#4
if(x == 4 and (line == top or line == bottom)) :
return digit[0]
if(x == 4 and (top < line < middle)) :
return digit[4]
if(x == 4 and (line == middle)) :
return digit[1]
if(x == 4 and (middle < line < bottom )) :
return digit[3]
#5
if(x == 5 and (line == top or line == middle or line == bottom)) :
return digit[1]
if(x == 5 and (top < line < middle)) :
return digit[2]
if(x == 5 and (middle < line < bottom)) :
return digit[3]
#6
if(x == 6 and (line == top or line == middle or line == bottom)) :
return digit[1]
if(x == 6 and (top < line < middle)) :
return digit[2]
if(x == 6 and (middle < line < bottom)) :
return digit[4]
#7
if(x == 7 and (line == top)) :
return digit[1]
if(x == 7 and (line == middle or line == bottom)) :
return digit[0]
if(x == 7 and (top < line < bottom)) :
return digit[3]
#8
if(x == 8 and (line == top or line == middle or line == bottom)) :
return digit[1]
if(x == 8 and (line != top or line != middle or line != bottom)) :
return digit[4]
#9
if(x == 9 and (line == top or line == middle or line == bottom)) :
return digit[1]
if(x == 9 and (top < line < middle)) :
return digit[4]
if(x == 9 and (middle < line < bottom)) :
return digit[3]
#0
if(x == 0 and (line == top or line == bottom)) :
return digit[1]
if(x == 0 and (line == middle)) :
return digit[0]
if(x == 0 and (line != top or line != middle or line != bottom)) :
return digit[4]
else :
return ""
#LCD display
def lcdDisplay(x):
setCriterion(x) #기준라인 정하기
line=[]
nu = (x * 2)+3
for z in range(nu):
line.append("")
initDigit() # 문자 초기화
makeDigit(x)# 대입 문자 만들기
digitnumber = len(inputNumber) #입력숫자의 길이 할당
lineNumber = len(line) #라인수 할당
for i in range(digitnumber):
for j in range(lineNumber):
line[j] += ' '+textToGraphic(int(inputNumber[i]), int(j+1))
for j in range(lineNumber):
print line[j]
#문자열이, 숫자(정수/실수)인지, 문자인지 체
def isNumber(s):
try:
float(s)
return True
except ValueError:
print "숫자가 아닌 문자열이 입력 되었습니다."
return False
#입력삽에 범위 검사
def isRange(s, n):
if((1<= int(s) < 10) != True):
print "첫번째 입력된 숫자가 범위를 벗어났습니다."
return False
if((9 < len(n))):
print "두번째 입력된 숫자가 범위를 벗어났습니다."
return False
return True
#입력창
def inputInterface():
arg1 = 1
arg2 = 1
prompt = """
첫번쨰 숫자를 문자을 표시하는 크기( 1<= s < 10 )를 의미
두번째 숫자는 n은 출력될 숫자( 0<= n <= 99,999,999 )를 의미
0 이 두 개 입력된 줄이 있으면 입력이 종료
입력 예
2 12345
3 67890
0 0
Enter nuber : """
while (arg1 != 0 or arg2 != 0) : #종료 조건
print prompt
arg0 = raw_input()
tmp = arg0.split()
if(len(tmp) != 2): #유효성 체크 1
print("문자를 2개 입력하세요")
else :
if(isNumber(tmp[0]) and isNumber(tmp[1])): #유효성 체크 2
arg1 = int(tmp[0])
arg2 = tmp[1]
if(arg1 == 0 and int(arg2) == 0): #while 종료 조건
break;
if(isRange(tmp[0], tmp[1])): #유효성 체크 3
if(arg1!= 0):
global inputNumber
inputNumber = arg2
lcdDisplay(arg1)
inputInterface()
실행화면
첫번쨰 숫자를 문자을 표시하는 크기( 1<= s < 10 )를 의미
두번째 숫자는 n은 출력될 숫자( 0<= n <= 99,999,999 )를 의미
0 이 두 개 입력된 줄이 있으면 입력이 종료
입력 예
2 12345
3 67890
0 0
Enter nuber :
2 12345
-- -- --
| | | | | |
| | | | | |
-- -- -- --
| | | | |
| | | | |
-- -- --
첫번쨰 숫자를 문자을 표시하는 크기( 1<= s < 10 )를 의미
두번째 숫자는 n은 출력될 숫자( 0<= n <= 99,999,999 )를 의미
0 이 두 개 입력된 줄이 있으면 입력이 종료
입력 예
2 12345
3 67890
0 0
Enter nuber :
3 67890
--- --- --- --- ---
| | | | | | | |
| | | | | | | |
| | | | | | | |
--- --- ---
| | | | | | | |
| | | | | | | |
| | | | | | | |
--- --- --- ---
첫번쨰 숫자를 문자을 표시하는 크기( 1<= s < 10 )를 의미
두번째 숫자는 n은 출력될 숫자( 0<= n <= 99,999,999 )를 의미
0 이 두 개 입력된 줄이 있으면 입력이 종료
입력 예
2 12345
3 67890
0 0
Enter nuber :
0 0
Perl 코드가 없어 leonid옹의 코드를 보고 간단히 만들어 봅니다.
chomp;/ /;exit if(!$` && !$');if($`&&$'>=0&&$'<=99999999){
foreach$l(28728,609961108,14680127,340862356,14708792){
$r="";foreach(split//,$'){$k=substr(' - | | ',7&$l>>$_*3,4);
substr($k,1,1,substr($k,1,1)x$`);$r.=$k;}print+($r."\n")x($l%7<1?1:$`);}}
저는 아라크넹옹이나 leonid옹처럼 코드골프를 하는 사람이 아니라서 충분히 최적화(?)를 하지 못했는데 다른 분들의 조언을 듣고 싶네요.

252바이트인데요. Ruby나 Python 코드처럼 조건을 체크하지 않으면 아래와 같은 코드이고 211바이트입니다.
chomp;/ /;if($`){foreach$l(28728,609961108,14680127,340862356,14708792)
{$r="";foreach(split//,$'){$k=substr(' - | | ',7&$l>>$_*3,4);substr($k,1,
1,substr($k,1,1)x$`);$r.=$k;}print+($r."\n")x($l%7<1?1:$`);}}
아무래도 델파이는 눈에 익지 않으실 듯 해서... C로 바꿔 올려봅니다.
MinGW로 컴파일 해보니 터보델파이 보다 300바이트 정도 작게 나오네요. ^^;;
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef char TDigitH [3];
typedef enum {dhN, dhH, dhVA, dhVL, dhVR} TDigitHType;
typedef TDigitHType TDigit [5];
const TDigitH DigitHTypes [] = {
{' ',' ',' '}, {' ','-',' '}, {'|',' ','|'},{'|',' ',' '}, {' ',' ','|'}
};
const TDigit DigitArray [] = {
// Digit 0 // Digit 1
{dhH, dhVA, dhN, dhVA, dhH}, {dhN, dhVR, dhN, dhVR, dhN},
// Digit 2 // Digit 3
{dhH, dhVR, dhH, dhVL, dhH}, {dhH, dhVR, dhH, dhVR, dhH},
// Digit 4 // Digit 5
{dhN, dhVA, dhH, dhVR, dhN}, {dhH, dhVL, dhH, dhVR, dhH},
// Digit 6 // Digit 7
{dhH, dhVL, dhH, dhVA, dhH}, {dhH, dhVR, dhN, dhVR, dhN},
// Digit 8 // Digit 9
{dhH, dhVA, dhH, dhVA, dhH}, {dhH, dhVA, dhH, dhVR, dhH}
};
void printDigitVLine(const TDigit aDigit, int aWidth, int aHeight, int aVLine)
{
int k =0, ii, ij;
int halfHeight = div(aHeight, 2).quot;
if (aVLine == 0) ii = 0; else
if (aVLine == aHeight-1) ii = 4; else
if (aVLine == halfHeight) ii = 2; else
if (aVLine < halfHeight) ii = 1; else
ii = 3;
while (k < aWidth) {
if (k == 0) ij = 0; else if (k == aWidth-1) ij = 2; else ij = 1;
putchar(DigitHTypes[aDigit[ii]][ij]);
k++;
}
putchar(' ');
}
void printDigitStr(char *aDigitStr, int aScale)
{
if (aScale < 1) return;
int i, j;
int Width = aScale + 2;
int Height = aScale * 2 + 3;
for (i=0; i<Height; i++) {
for (j=0; j<strlen(aDigitStr); j++) {
printDigitVLine(DigitArray[aDigitStr[j]-'0'], Width, Height, i);
}
printf("\n");
}
}
void FileProc(char *aFileName)
{
FILE *in;
if (in=fopen(aFileName, "r")) {
int Scale;
char DigitStr[100];
while (0 < fscanf(in, "%d %s", &Scale, &DigitStr)) {
if (Scale == 0 && strcmp(DigitStr, "0") == 0) break;
printDigitStr(DigitStr, Scale);
printf("\n");
}
fclose(in);
} else {
printf("Can't open input file\n");
return;
}
}
int main(int argc, char *argv[])
{
if (argc > 1)
FileProc(argv[1]);
else
printf("No input file\n\n");
printf("Press any key...");
getchar();
return 0;
}
타입명에 T를 붙이는 것과 변수명에 대소문자 섞는 건 델파이를 오래 써온 습관이니 눈감아주시와요.
"CodeJob input.txt" 했을 때 출력화면 입니다.

재미난 퀴즈 다시 한 번 감사드려요~~ 코드잡의 무한한 발전을 기원합니다~~^^;;
ps. 숫자사이에 컬럼 하나를 띄우는 걸 까먹어 수정했습니다, ^^
정말로 삭제하시겠습니까?
정말로 삭제하시겠습니까?
인터넷 익스플로러6는 지원하지 않습니다.