일반적인 트럼프 카드는 클로버(c), 스페이드(s), 하트(h), 다이아몬드(d) 4개의 문양과 1~13까지의 숫자로 조성된 52개의 카드와 두 장의 조커가 있습니다. 이 문제에서는 조커를 뺀 52장만 다룹니다.
트럼프 카드의 deck이 처음에 위에서부터 순서대로 클로버 1~13, 스페이드 1~13, 하트 1~13, 다이아몬드 1~13으로 쌓여있습니다. 카드을 한 번 섞는다는 것을 이렇게 정의하겠습니다.
1) 처음에 카드 더미를 반절로 나눠서 아래 반을 위로 올립니다.
2) 올린 카드의 반절을 다시 위로 올립니다.
3) 만약 반절로 나눌 더미가 홀수 장이면 반절의 짝수장을 올립니다.(예 : 13장이면 6장을 위로 올림)
4) 이 과정을 반복해서 위에 올린 카드가 1장이면 카드를 한 번 섞은 것입니다.
입력
첫번째 숫자는 카드를 섞은 횟수(10번 이하)이고, 두번째 문자는 클로버(c), 스페이드(s), 하트(h), 다이아몬드(d)이며, 세번째 숫자는 카드의 숫자입니다(1은 A, 11은 J, 12는 Q, 13은 K).
2 s 11
출력
입력한 카드가 위에서 몇번째에 있는지를 출력합니다.
3
입력받은 횟수만큼 카드를 섞었을 때 입력한 카드가 위에서 몇번째에 있는지를 출력하는 프로그램을 작성하세요.
15개의 풀이가 있습니다.
# n장의 카드 더미에서 아래 절반을 위로 올림. 찾는 카드는 위에서 p번째에 있음
def invert_half_rec(n, p):
if n <= 1 or n < p:
return p
n_lower = n // 2 + ((n+1) % 4 == 0)
n_upper = n - n_lower
if p <= n_upper:
return invert_half_rec(n_lower, p + n_lower)
else:
return invert_half_rec(n_lower, p - n_upper)
def card_shuffle(n_shuffle, suit, number):
p = "cshd".index(suit) * 13 + number
for _ in range(int(n_shuffle)):
p = invert_half_rec(52, p)
return p
n_shuffle, suit, number = input().split()
print(card_shuffle(int(n_shuffle), suit, int(number)))
L = [x+str(y+1) for x in 'cshd' for y in range(13)]
L = L[::-1]
def shuffle():
n, start = 52, 0
while n:
for _ in range(round(n/2)): L.append(L.pop(start))
n, start = round(n/2), start + (n-round(n/2))
a, b, c = input().split()
for _ in range(int(a)): shuffle()
print(L[::-1].index(b+c) + 1)
const Card = (function(){
function Card(n, shape){
this.n = n;
this.shape = shape;
}
Card.prototype.is = function(n, shape){
return this.n === n && this.shape === shape;
};
return Card;
})();
const shuffleOrder = (function(){
var deck = [];
for(let i=0; i<52; i++)
deck.push(i);
return (function shuffle(deck){
var len = deck.length;
var cnt = len&1 ? len>>1|1 : len>>1;
return len === 1 ?
deck :
shuffle(deck.slice(cnt)).concat(deck.slice(0, cnt));
})(deck);
})();
const initDeck = ( ()=>{
var deck = [];
for(let j of 'cshd')
for(let i=1; i<=13; i++)
deck.push( new Card(i,j) );
return deck;
})();
const getOrder = function(shuffleCount, shape, n){
var id = initDeck.findIndex( el => el.is(n, shape) );
for(let i=0; i<shuffleCount; i++)
id = shuffleOrder.indexOf(id);
return id + 1;
}
console.log( getOrder(2, 's', 11) );
console.log( getOrder(20, 's', 11) );
console.log( getOrder(200, 's', 11) );
console.log( getOrder(2000, 's', 11) );
console.log( getOrder(200000, 's', 11) );
console.log( getOrder(200002, 's', 11) );
3
16
22
24
24
3
Ruby
def card_index_of_shuffled
rule, deck = [26, 13, 6, 3, 2, 1], %w(c s h d).product([*'1'..'13'])
shuffle = ->deck,i { deck[1] ? shuffle[deck.pop(rule[i]), i+1] + deck : deck }
repeat = ->n,fn { ([0]*n.to_i).reduce(deck, &fn) }
n_times, *card = gets.split
puts repeat[n_times, shuffle].index(card) + 1
end
Test
# stdin/out test
$stdin = StringIO.new("2 s 11\n")
expect { index_of_shuffled }.to output("3\n").to_stdout
C++
#include<iostream>
using namespace std;
#define TOTAL_CARD_NUM 52
enum CARD_MARK { NONE = -1, C, S, H, D };
int Shuffle_cycle(int card_pos, int card_num) {// 재귀함수
if (card_num > 1) {
int half_num = card_num / 2;
if (card_num % 2 == 1 && half_num % 2 == 1) { half_num++; }//뒤에서 앞으로 움직일 카드양
if (card_pos > card_num - half_num) {
card_pos -= (card_num-half_num);
Shuffle_cycle(card_pos, half_num);
}
else {
card_pos += half_num;
return card_pos;
}
}
else {
return 1;
}
}
int Shuffle_N_time(int card_pos, int Shuff_NUM) {
int p = card_pos;
for (int i = 0; i < Shuff_NUM; i++) {
p = Shuffle_cycle(p, TOTAL_CARD_NUM);
}
return p;
}
int MarkToPos(char Mark, int num) {
enum CARD_MARK Card_factor = NONE;
switch (Mark)
{
case 'c':
Card_factor = C;
break;
case 's':
Card_factor = S;
break;
case 'h':
Card_factor = H;
break;
case 'd':
Card_factor = D;
break;
default:
Card_factor = NONE;
}
return (Card_factor != NONE && num >= 1 && num <= 13) ? Card_factor * 13 + num : -1;
}
int main() {
int Shuffle_Num, num, card_pos;
char Mark;
cin >> Shuffle_Num;
cin >> Mark;
cin >> num;
card_pos = MarkToPos(Mark, num);
if (card_pos != -1 && Shuffle_Num > 0) {
cout << Shuffle_N_time(card_pos, Shuffle_Num) << endl;
}
else {
cout << "input error" << endl;
}
return 0;
}
C++ 입니다
#include <iostream>
#include <cstdio>
#include <deque>
#include <string>
using namespace std;
deque<string> make_deck() // 카드 덱 생성 함수
{
deque<string> deck;
string shape = "cshd";
for (int i = 0; i < 4; ++i)
{
for (int j = 1; j <= 13; ++j)
{
deck.push_back(string(1, shape[i]) + " " + to_string(j));
}
}
return deck;
}
deque<string> shuffle_card(deque<string> half, int len = 52) // 섞는 함수(재귀)
{
if (len == 1) return half;
deque<string> result = shuffle_card(deque<string>(half.begin() + (len+1)/2, half.end()), len/2);
result.insert(result.end(), half.begin(), half.begin() + (len+1)/2);
return result;
}
int main()
{
deque<string> deck = make_deck(); // 덱
string shape;
//int num;
int attemps;
cin >> attemps; // 섞는 횟수 입력
getline(cin, shape); // 찾을 카드 입력
shape.erase(0, 1); // 공백 제거
for (int i = 0; i < attemps; ++i) // attemps 번 섞기
{
deck = shuffle_card(deck);
}
deque<string>::iterator it = find(deck.begin(), deck.end(), shape); // shape의 위치를 가지고 있는 반복자
cout << it - deck.begin() + 1 << endl;
return 0;
}
Deck_Clover = ['c1','c2','c3','c4','c5','c6','c7','c8','c9','c10','c11','c12','c13']
Deck_Space = ['s1','s2','s3','s4','s5','s6','s7','s8','s9','s10','s11','s12','s13']
Deck_Heart = ['h1','h2','h3','h4','h5','h6','h7','h8','h9','h10','h11','h12','h13']
Deck_Diamond= ['d1','d2','d3','d4','d5','d6','d7','d8','d9','d10','d11','d12','d13']
TotalDeck = Deck_Clover + Deck_Space + Deck_Heart + Deck_Diamond
def Shuffle1 (Deck):
if len(Deck) % 2 == 0:
HalfLen = len(Deck) // 2
else :
HalfLen = (len(Deck) + 1) // 2
return Deck[HalfLen:],Deck[:HalfLen]
def Shuffle2(Deck):
Answer1 = []
Answer2 = []
while True:
Result = Shuffle1(Deck)
if len(Result[0]) == 0:
Answer1.append(Result[1])
break
else :
Deck = Result[0]
Answer1.append(Result[1])
Answer1.reverse()
for i in Answer1:
for j in i:
Answer2.append(j)
return Answer2
inputNum = input()
Num = inputNum.split()
Find = Num[1]+Num[2]
n = 0
while n != int(Num[0]):
TotalDeck = Shuffle2(TotalDeck)
n = n + 1
print(TotalDeck.index(Find)+1)
python 3.7
a, b, c = input().split(' ')
d = [i+str(j) for i in 'cshd' for j in range(1,14)]
def shuffle(n, deck):
if n < 1:
return deck
else:
r = deck[:48:-1]+deck[46:49]+deck[39:46]+deck[26:39]+deck[:26]
n -= 1
return shuffle(n, r)
print (shuffle(int(a), d).index(b+c)+1)
import random
k={'c':0.0,'h':0.1,'d':0.2,'s':0.3}
card=[]
for i in range(4):
shape=i/10
for j in range(13):
card.append(j+shape)
random.shuffle(card)
def shuffle(n):
for j in range(n):
for i in range(int(52/((j+1)*2))):
a=card[i]
card[i]=card[int((52/((j+1)*2)))+i-1]
card[int((52/((j+1)*2)))+i-1]=a
sf=input("셔플 횟수를 입력하세요:")
sp=input("모양을 입력하세요:")
nb=input("숫자를 입력하세요")
shuffle(int(sf))
r_shape=k[sp]
r_number=int(nb)+r_shape
print(card.index(r_number))
JAVA
public class Card_Shuffle_1 {
Card[] deck = new Card[52];
Card_Shuffle_1(){
createdeck();
}
void createdeck(){
char[] pattern = {'d','h','s','c'};
int i = 0;
for (char p : pattern) {
for(int j = 13; j >= 1; j--){
deck[i] = new Card(p, j);
i++;
}
}
}
Card[] shuffle(Card[] deck){
int bottomcnt = deck.length/2;
int topcnt = deck.length - bottomcnt;
if(bottomcnt == 0){
return deck;
}
Card[] deckTmp = new Card[bottomcnt];
for(int i = 0; i < topcnt; i++){
if(i < bottomcnt){
deckTmp[i] = deck[i];
deck[i] = deck[bottomcnt + i];
}else{
deck[i] = deck[bottomcnt + i];
}
}
deckTmp = shuffle(deckTmp);
for(int i = topcnt; i < deck.length; i++){
deck[i] = deckTmp[i - topcnt];
}
return deck;
}
void fatchDeck(int a){
for(int i = 0; i < a; i++){
deck = shuffle(deck);
}
}
void whereCard(int cnt, char p, int num){
fatchDeck(cnt);
for(int i = 0; i < deck.length; i++){
if(deck[i].pattern == p)
if(deck[i].num == num)
System.out.println(cnt + "번 섞은 덱에서 " + p + num + "의 위치는 : " + (deck.length - i));
}
}
void printDeck(){
for (Card cardTmp : deck){
System.out.println(cardTmp);
}
}
public static void main(String[] args){
Card_Shuffle_1 cs = new Card_Shuffle_1();
cs.whereCard(2, 's', 11);
}
}
class Card{
char pattern;
int num;
Card(char pattern, int num){
this.pattern = pattern;
this.num = num;
}
@Override
public String toString() {
return "Card [pattern=" + pattern + ", num=" + num "]";
}
}
열심히 해봤습니다 ^^ 코드가 많이 기네요 ㅠㅠ
import java.util.Scanner;
public class CardShuffle {
private final int totalCards=52;
private int shuffling=0;
private String mark="";
private String cardNumber="";
private String[] deck=new String[totalCards];
public void startGame() {
initCard();
getData();
for(int i=1;i<=shuffling;i++)
shuffle(totalCards/2,totalCards);
int result=findCard(mark,cardNumber);
System.out.println("찾는 카드 : "+(mark+cardNumber)+" / 위치 : "+result);
}
private void initCard() {
//카드 맨 앞이 배열의 첫번쨰라고 생각하고 초기화.
int count=1;
for(int i=0;i<totalCards;i++) {
if(count==14)
count=1;
if(i<13 )
deck[i]="c"+String.valueOf(count);
else if(i<26)
deck[i]="s"+String.valueOf(count);
else if(i<39)
deck[i]="h"+String.valueOf(count);
else
deck[i]="d"+String.valueOf(count);
count++;
}
}
//데이터를 입력받는 함수.
private void getData() {
Scanner scan=new Scanner(System.in);
System.out.print("카드 섞을 횟수 입력 : ");
shuffling=scan.nextInt();
System.out.println();
System.out.print("찾을 모양입력(c,s,h,d) : ");
mark=scan.next();
System.out.println();
System.out.print("찾을 카드 숫자 입력(1~13) : ");
cardNumber=scan.next();
System.out.println();
}
private void shuffle(int mid,int last) {
//System.out.println("mid:"+mid +" lst:"+last);
int tempMid=mid;
int tempIndex=0;
//절반 섞기위한 임시 절반 카드덱
String halfDeck[]=new String[mid];
//기저조건
if(mid==0)
return;
//홀수일때 아래 절반을 위로 올려주기 위해 mid를 +1해줘야함. 예)13개일떄 위7개를 뺴고 아래 6장을 올려야함
//이 분기문이 없다면 위 6장제외하고 아래 6장 을려버림(셔플 오류)
if(last%2==1)
tempMid++;
//임시카드덱에 섞을 카드 절반을 복사해줌.
for(int i=tempMid;i<last;i++) {
halfDeck[tempIndex]=deck[i];
//System.out.println("halfDeck["+tempIndex+"] : "+halfDeck[tempIndex]+" deck["+i+"] : "+deck[i]);
tempIndex++;
}
//카드덱위절반을 아래로 내려주면서
//임시카드덱에 복사한 값들을 넣어줌.
for(int i=0;i<mid;i++) {
deck[tempMid]=deck[i];
deck[i]=halfDeck[i];
tempMid++;
}
//재귀호출.
shuffle(halfDeck.length/2,halfDeck.length);
}
//입력한 카드를 찾기위한 함수.
//카드가 52장 밖에 안되기 때문에 아래부터 차례로 찾음.
//만약 카드수가 1000장 10000장 마구마구 늘어난다면 찾는 로직을 바꿔야함..(속도문제때문)
private int findCard(String mark,String number) {
String objMark=mark+number;
for(int i=0;i<totalCards;i++) {
if(deck[i].equals(objMark)) {
return ++i;
}
}
return 0;
}
//이건 카드가 잘 섞였나 확인하기 위한 메소드
public void showCard() {
System.out.println("====================");
for(int i=0;i<totalCards;i++) {
System.out.println(deck[i]);
}
System.out.println("====================");
}
}
card = [] # 13단위로 c, s, h, d 구분
c, s, h, d, card_shape = 0, 13, 26, 39, 0
for a in range(1, 53):
card.append(a)
def round_up(n):
if n % 2 == 1:
return int(n/2)+1
else:
return int(n/2)
def shuffle(deck):
deck1, deck2 = [], []
for a1 in deck[:round_up(int(len(deck))):1]:
deck1.append(a1)
for a2 in deck[round_up(int(len(deck)))::1]:
deck2.append(a2)
if len(deck1) % 2 == 0 and len(deck2) % 2 == 1:
temp = deck1.pop(-1)
deck2.insert(0, temp)
if len(deck2) == 1:
return deck2 + deck1
return shuffle(deck2) + deck1
enter = input().split()
count, shape, number = int(enter[0]), str(enter[1]), int(enter[2])
if shape == 'c':
card_shape += c
elif shape == 's':
card_shape += s
elif shape == 'h':
card_shape += h
elif shape == 'd':
card_shape += d
x = 0
while x < count:
card = shuffle(card)
x += 1
print(card.index(card_shape + number)+1)
// Rust
// 답은 2입니다. s13, s11, s12, s8, ... 순
fn card_shuffle() {
let times = 2;
let input = ('s', 11);
let mut deck = vec![];
for c in ['c', 's', 'h', 'd'] {
for i in 1..=13 { deck.push((c, i));}}
for _ in 1..=times {
let mut front_n = deck.len();
while front_n > 1 {
deck = shuffle(deck, front_n);
front_n /= 2; }}
println!("{:?}", deck);
println!("{}", deck.iter().position(|&d| d == input).unwrap() + 1);
} fn shuffle(mut deck: Vec<(char, u8)>, front_n: usize) -> Vec<(char, u8)> {
let mut start = front_n / 2;
if front_n % 2 != 0 { start += 1; }
let mut front: Vec<(char, u8)> = deck.drain(start..front_n).collect();
front.extend(deck.iter());
front
}
python
def shuffle(deck):
dec1 = deck[0:26]
dec2 = deck[26:]
dec3 = dec2[0:13]
dec4 = dec2[13:]
dec5 = dec4[0:7]
dec6 = dec4[7:]
dec7 = dec6[0:3]
dec8 = dec6[3:]
dec9 = dec8[:1]
dec10 = dec8[1:]
dec11 =dec10[:1]
dec12 = dec10[1:]
deck = dec12 + dec11 + dec9 + dec7 + dec5 + dec3 + dec1
return deck
num = int(input("카드를 섞을 횟수를 입력해주십시오(단 10이하): "))
shape = input("카드모양을 입력해주십시오(클로버는 c, 스페이드는 s, 하트는 h, 다이아몬드는 d): ")
card_num = input("카드숫자를 입력해주십시오(1~13): ")
card = shape + card_num
shape_list = ['c', 's', 'h', 'd']
deck = [s + str(n) for s in shape_list
for n in range(1, 14)]
for i in range(num):
deck = shuffle(deck)
find = deck.index(card) + 1
print(f"입력한 카드는 위에서 {find}번째에 있습니다")
import numpy as np
import math
# 카드 덱 초기화 설정
deck = np.zeros((52,3))
for n in range(4):
k = 1
for i in range(13*n,13*(n+1)):
deck[i][2] = k
k = k+1
deck = deck.tolist()
for n in range(4):
for i in range(13*n,13*n+13):
if n == 0:
deck[i][1] = 'c'
if n == 1:
deck[i][1] = 's'
if n == 2:
deck[i][1] = 'h'
if n == 3:
deck[i][1] = 'd'
# 카드 입력값
card = input('카드(ex. 2 s 11): ')
shuffle, pattern, num = card.split(' ')
#셔플 횟수(입력값의 첫번째 항)만큼 셔플 수행
for big_turn in range(0, int(shuffle)):
# 셔플 1회
for turn in range(1,6):
temporary_deck = []
card_number = 52/(2**(turn-1))
shuffle_number = math.floor(card_number/2)
moving_card = int(card_number)-shuffle_number
temporary_deck[0:shuffle_number] = deck[0:shuffle_number]
deck[0:shuffle_number] = deck[moving_card:math.floor(card_number)]
deck[moving_card:math.floor(card_number)] = temporary_deck[0:shuffle_number]
#셔플 1회마다 셔플 횟수 1 증가
for k in range(52):
deck[k][0] = deck[k][0]+1.0
#결과 출력
m = 0
while m<52:
if deck[m][1] == pattern and deck[m][2] == float(num):
print('카드 위치: ', m+1)
break
else:
m = m + 1