이 페이지는 코딩도장 데이터의 읽기 전용 정적 보관본입니다.

핑퐁게임

출처: https://brunch.co.kr/@sunghokimnxag/5

일련의 숫자가 있고, 이 숫자는 1씩 증가, 또는 감소한다. n번째의 숫자가 있을 시에, 이 숫자가 7의 배수(7, 14, 21,...)거나 7이란 숫자를 포함할 시에 (7, 17, 27,...) 방향을 바꾼다.

즉, 다음과 같이 숫자는 진행한다.

1,2,3,4,5,6,[7],6,5,4,3,2,1,[0],1,2,[3],2,1,0,[-1],0,1

(첫 번째 7은 7번째, 두번째 0은 14번째, 세번째 3은 17번째, 네번째 -1은 21번째)

이와 같은 pingpong(x)의 함수를 작성하라. 예시의 인풋과 아웃풋은 다음과 같다.

pingpong(8) = 6
pingpong(22) = 0
pingpong(68) = 2
pingpong(100) = 2

심화학습

위 문제에 다음과 같은 제약을 추가하여 다시 풀어보자.

  • For Loop 또는 Array를 쓰지 말 것
  • Assignment를 쓰지 말 것, 즉, 변수 할당을 하지 말 것.
  • String을 쓰지 말 것
면접문제 재귀호출

2016/07/22 15:00

pahkey

죄송하지만 저한테 조금 어려워서 그러는데 진행이 끝나는 곳이 어디죠? - 최승호, 2016/07/23 21:39
pingpong 함수의 입력이 8이면 8번째 해당 하는 값이 출력되면 되구요, 100이면 100번째 해당하는 값을 출력하면 됩니다. - pahkey, 2016/07/24 16:12
뭔 말인가 해서 한참 봤네요. "이 숫자가 7의 배수..." --> "n이 7의 배수..." - Noname, 2017/08/19 01:24
Array 라는 건 리스트는 몰론 딕셔너리, 튜플도 쓰지 말라는 건가요? - 김영성, 2018/06/25 20:14

47개의 풀이가 있습니다.

Ruby

3가지로 품. ( list조작 + 문자열, list 조작 + 문자열 사용않기, recursion + 아무것도 사용않기)

string, list comprehension - 쉽게 풀기

sevens = ->nth { (0..nth).select {|n| n%7==0 || n.to_s.include?("7") || n==nth} }
pingpong = ->x { sevens.(x).each_cons(2).map {|a,b| b-a }.map.with_index.
                           reduce(0) {|sum,(gap,i)| sum + gap*(i.odd?? -1:1)} }
# test
expect( [8,22,68,100,10000,100000].map &pingpong ).to eq [6, 0, 2, 2, -122, 212]
expect( Benchmark.realtime { pingpong.(100000) } ).to be_between(0.001, 0.1)

list comprehension - string 쓰지 않기

is_7 = ->n { n.abs<10 ? (n.abs==7) : is_7.(n/10) || is_7.(n%10) }
sevens = ->nth { (0..nth).select {|n| is_7.(n) || n%7==0 || n==nth } }
pingpong = ->x { sevens.(x).each_cons(2).map {|a,b| b-a }.
                        map.with_index {|gap,i| gap * (i.odd?? -1:1) }.sum }
# test
expect( [7, 17, -7].all? &is_7 ).to be_truthy # 7s
expect( [8,  0, -2].all? &is_7 ).to be_falsy  # not 7s
expect( sevens.(20) ).to eq [0, 7, 14, 17, 20]
expect( [8, 22, 68, 100].map(&pingpong) ).to eq [6, 0, 2, 2]
expect( Benchmark.realtime { pingpong.(100000) } ).to be_between(0.001, 0.2)

recursion - 아무것도 쓰지 않기

is_7 = ->n { n.abs<10 ? n.abs==7 : is_7[n/10] || is_7[n%10] || n%7==0 }
pingpong = proc do |nth, idx, val, inc|
  idx.nil? ? pingpong.(nth, 1, 1, 1) : idx == nth ? val : 
             pingpong.(nth, idx+1, val+inc, is_7.(idx+1) ? -inc : inc )                         
end
# test
expect( [8, 22, 68, 100].map(&pingpong) ).to eq [6, 0, 2, 2]
expect( Benchmark.realtime { pingpong.(1000) } ).to be_between(0.0001, 0.01)

2016/07/23 05:45

rk

변수를 선언하면 안된다는 조건은 통과하지 못했습니다. 재귀를 사용했는데 이또한 1000 이상은 maximum limit때문에 계산이 불가능하네요.

파이썬입니다..

def has7(n):
    return n % 7 == 0 or (n % 10 and n % 10 % 7 == 0) \
        or (n // 10 and has7(n // 10))


def pingpong(limit, val=1, direction=1, count=1):
    if(count==limit): return val
    if has7(count): direction = -direction
    return pingpong(limit, val+direction, direction, count+1)


import unittest

class PingPongTest(unittest.TestCase):
    def test_has7(self):
        self.assertTrue(has7(7))
        self.assertFalse(has7(8))
        self.assertFalse(has7(10))
        self.assertTrue(has7(7*22))
        self.assertTrue(has7(17))
        self.assertTrue(has7(170))
        self.assertTrue(has7(178))

    def test_pingpong(self):
        self.assertEqual(6, pingpong(8))
        self.assertEqual(0, pingpong(22))
        self.assertEqual(2, pingpong(68))
        self.assertEqual(2, pingpong(100))


if __name__ == "__main__":
    unittest.main()

2016/07/25 13:50

pahkey

이런식으로 처리하면 될 것 같습니다.


int pingpong(char *wantto){
    int ret = 0;    int count = 1;  int realdata = 1;   int wanttoint = 0;  char wanttostr[20];
    wanttoint = atoi(wantto);
    while(1){
        snprintf(wanttostr, 20, "%d",count);
        ret = realdata;
        if(count == wanttoint) break;
        if(count % 7 == 0 || strstr(wanttostr, "7")){
            while(1){
                count++;
                snprintf(wanttostr, 20, "%d",count);
                realdata --;
                ret = realdata;
                if(count == wanttoint || count % 7 == 0 || strstr(wanttostr, "7"))  break;
            }
        }
        if(count == wanttoint) break;
        count++; realdata++;
    }
    return ret;
}

2016/07/27 20:25

히알루미니

C샵

  • For Loop 또는 Array를 쓰지 말 것
  • Assignment를 쓰지 말 것, 즉, 변수 할당을 하지 말 것.
  • String을 쓰지 말 것

제약모두지킴.

1000이상, 10000이상도 됨.

using System;

namespace ConsoleApplication
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.Write("{0}\t", pingpong(8));
            Console.Write("{0}\t", pingpong(22));
            Console.Write("{0}\t", pingpong(68));
            Console.Write("{0}\t", pingpong(100));
            Console.Write("{0}\t", pingpong(1000));
            Console.Write("{0}\t", pingpong(10000));
            Console.ReadKey();
        }

        static int pingpong(int n)
        {
            return n == 1 ?  1 : pingpong(n - 1) + getIncVal(n);
        }

        static int getIncVal(int n)
        {
            return n == 1 ? 1 : (n - 1) % 7 == 0 || isInclude7Cnt(n - 1) ? -getIncVal(n - 1) : getIncVal(n - 1);
        }

        static bool isInclude7Cnt(int n)
        {
            return n == 0 ? false : n % 10 == 7 ? true : isInclude7Cnt(n / 10);
        }
    }
}

2016/09/12 12:59

이 종성

string말고는 없애기가 힘드네요..

int sevenBool(int numbering) {
    if (numbering % 7 == 0 || numbering % 10 == 7) {
        return -1;
    }
    else if (numbering / 10 != 0) {
        return sevenBool(numbering / 10);
    }
    else {
        return 1;
    }
}
int pingpong(int pingpongCount) {
    int direction = 1;
    int result = 0;
    for (int i = 1; i <= pingpongCount; i++) {
        result = result + direction;
        direction = direction * sevenBool(i);
    }
    return result;
}

2016/07/26 15:26

김 진태

자바스크립트로 짜봤습니다.

    function check7(value){
        return (value%7==0||(/7/).test(value)) ? -1 : 1;
    }
    function pingpong(value,cnt, returnVal, direction){
        cnt = cnt==undefined ? 1 : cnt;
        returnVal = returnVal==undefined ? 1 : returnVal;
        direction = direction==undefined ? 1 : direction;

        return (value==cnt) ? returnVal
        : pingpong(value, cnt+1, returnVal+direction, direction*check7(cnt+1));

    }
    console.log(pingpong(8));
    console.log(pingpong(22));
    console.log(pingpong(68));
    console.log(pingpong(100));

2016/07/29 15:39

병아리

조건이 하나 빠진 거 같아서 원문까지 살펴봤는데요, n 은 1000 미만이라는 조건이 붙어야 제약을 적용해서 풀이가 가능할 것 같은데 원문에도 그 언급이 그냥 뒤에서 슬그머니 나오네요.

def pingpong(n: int) -> int:
    def has7(x: int, first=True) -> bool:
        if x is 0:
            return False
        elif first:
            if x % 7 is 0 or x % 10 is 7:
                return True
        elif x % 10 is 7:
            return True
        else:
            return has7(x//10, False)

    def inner(count=1, step=1, result=1):
        if count == n:
            return result
        return inner(count+1, step if has7(count) else -step, result+ (step if has7(count) else -step))
    return inner()

print(pingpong(997))

n의 크기를 한정할 수 없다고 가정하면 7이 있는지 여부를 찾는 부분도 재귀로 구성해야 합니다. 그러면 실질적으로는 997까지의 값만 구할 수 있습니다. (재귀스택에서 has7이 써버리는 부분이 있다보니..)

만약, 할당을 허용한다고 하면 꼬리재귀 호출 대신에 다음 재귀 호출에 넘길 인자를 튜플로 리턴하는 식으로 코드를 약간 뜯어고쳐서 반복문으로 만들 수 있습니다.

def pingpong(n: int) -> int:

    def has7(x: int, first=True) -> bool:
        if x is 0:
            return False
        elif first:
            if x % 7 == 0 or x % 10 is 7:
                return True
        elif x % 10 is 7:
            return True
        else:
            return has7(x//10, False)

    def inner(count=1, step=1, result=1):
        if count == n:
            return result
        return (count+1, step if has7(count) else -step, result+ (step if has7(count) else -step))

    r = inner()
    while not isinstance(r, int):
        r = inner(*r)
    return r

print(pingpong(1000000))

2016/08/18 09:32

룰루랄라

    private static void pingpongRestriction(int end) {
        System.out.println("pingpong (" + end + ") = " + recursiveFunc(end, 1, 1, 1));
    }

    // end          : 종료 횟수
    // count        : 회차
    // result       : 회차의 결과값
    // fluctuation  : 증감값
    private static int recursiveFunc(int end, int count, int result, int fluctuation) {

        if (count == end) {
            return result;
        } else {
            return recursiveFunc(end, count + 1, result + (fluctuation * fluctiationFunc(count)), fluctuation * fluctiationFunc(count));        
        }
    }

    //증감
    private static int fluctiationFunc(int count) {
        return ( ((count % 7) == 0) || ((count % 10) == 7) || ((count / 10) == 7) ) ? -1 : 1;
    }

2016/08/18 14:29

OPTISJ

#include <stdio.h>

int pm(int num)
{
    if (num == 0) return 1;

    if (num % 7 == 0 || num % 10 == 7 || (num / 10) % 10 == 7 || num / 100 == 7)
        return -pm(num - 1);
    else
        return pm(num - 1);
}

int pingpong(int num)
{
    if (num == 1) return 1;

    return pingpong(num - 1) + pm(num - 1);
}

void main(void)
{
    printf("%d\n",pingpong(8));
    printf("%d\n", pingpong(22));
    printf("%d\n", pingpong(68));
    printf("%d\n", pingpong(100));
}

2016/08/26 16:08

심 규원

허접한 풀이!! ㅠ,.ㅠ

#include<stdio.h>
#include<windows.h>

struct Sseq {
    int seq;
    int out;
};

int pingpong(int input);

Sseq s;
int temp;
char ch;

void main(void) {
    int input;

    ch = '+';
    s.out = 1;
    s.seq = 1;
    temp = 0;

    printf("#입력 : ");
    scanf("%d", &input);

    printf("\n#출력 : ");
    printf("%d\n", pingpong(input));


}

int pingpong(int input) {

    if(((s.seq % 7) == 0 || (s.seq % 10) == 7  || (s.seq/7)%10 == 0) && s.seq/7!=0) {
        if(temp < s.out)
            ch='-';
        else 
            ch='+';
    }
    if(ch == '-') {
        temp = s.out;
        s.out--;
    }
    else {
        temp = s.out;
        s.out++;
    }

    s.seq++;
    input--;

    if(input > 1)
        return pingpong(input);
    else
        return s.out;
}

2016/08/28 16:14

코딩초보

자바

package study;

public class study {

    public static void main(String[] args) {
        System.out.println("pingpong(" + 8 + ") = " + pingpong(8));
    }

    public static int pingpong(int n) {
        int dir = 1, result = 0;

        for (int i = 1; i < n + 1; i++) {
            if (dir == 1) {
                result++;
            } else {
                result--;
            }

            if (i % 7 == 0 || i % 10 == 7 || (i / 10) % 10 == 7 || (i / 100) % 10 == 7 || (i / 1000) % 10 == 7) {
                dir = (dir + 1) % 2;
            }
        }

        return result;
    }
}

귀찮아서 String 안 쓰고 4자리까지만 되게 했습니다 추가조건은 어려워서 요까지만...

2016/09/09 09:29

JD

재미있네요 ㅋㅋ


#define PINGPONG_MULTIPLES_OF_SEVEN(n)     (bool)(n % 7 == 0)

bool pingpong_contains_seven(int num)
{
    if (num >= 10)
    {
        if (num % 10 == 7)
            return true;

        return pingpong_contains_seven(num / 10);
    }

    return num == 7;
}

int pingpong_check(int value, bool increased, int play_num, int play_max)
{
    if (play_num > play_max)
        return value;

    if (PINGPONG_MULTIPLES_OF_SEVEN(play_num) ||
        pingpong_contains_seven(play_num))
        return pingpong_check(increased ? value + 1 : value - 1, !increased, play_num + 1, play_max);

    return pingpong_check(increased ? value + 1 : value - 1, increased, play_num + 1, play_max);
}

int pingpong(int number)
{
    return pingpong_check(0, true, 1, number);
}


        printf("%d : %d\n", 8, pingpong(8));
        printf("%d : %d\n", 22, pingpong(22));
        printf("%d : %d\n", 68, pingpong(68));
        printf("%d : %d\n", 100, pingpong(100));

8 : 6 22 : 0 68 : 2 100 : 2

2016/09/22 16:36

이 광표

def _7(n):
    if n%10 == 7: return True
    elif n == n%10: return False
    else: return _7(n//10)
def p(n, i, s, d):
    if n == i: return s
    if i%7 == 0 or _7(i): return p(n, i+1, s-d, (-d))
    else: return p(n, i+1, s+d, d)
def pingpong(n): return p(n, 1, 1, 1)

print(pingpong(8))
print(pingpong(22))
print(pingpong(68))
print(pingpong(100))

제약은 다 지켰지만 실제로 쓰기에는 무리가 있네요.큰 수 넣으면 재귀 최대 깊이 초과라 그냥 루프 돌리는 것이 코딩도 쉽고 안정적일 것 같네요.

2016/10/22 01:22

Flair Sizz

파이썬3.5

import sys
sys.setrecursionlimit(10000)

def has_7(n):

    if n == 0:
        return False

    elif n%7 == 0 or n%10 == 7:
        return True

    elif n%10 == n:    # 위 조건과 자리 바뀌면 안됨
        return False

    else:
        return has_7(n//10)


def f(x, i=1, n=1, step=1):

    if x == i:
        return n

    if has_7(i):
        return f(x, i+1, n-step, step*-1)    # n-step 주의

    return f(x, i+1, n+step, step)

f(8), f(22), f(68), f(100), f(1000)

2016/10/27 13:37

디디

문제 뼈대를 옮겨보면..

int main(int argc, const char * argv[]) {
    printf("%d\n", pingpong(8));
    printf("%d\n", pingpong(22));
    printf("%d\n", pingpong(68));
    printf("%d\n", pingpong(100));
    return 0;
}

자리 인덱스 n을 1부터 시작하므로 루프에서 for (int i=1; i<=n; i++)처럼...

int pingpong(int n) {
    int step = 1;
    int value = 0;
    for (int i=1; i<=n; i++) {
        value += step;
        if (i % 7 == 0 || contains7(i) ) { // 7의배수거나 7을 포함하거나..
            step = -step;
        }
    }
    return value;
}

7을 포함하는 것은 각 자릿수(%10)를 확인하면 됩니다.

int contains7(int n) {
    while (n > 0) {
        if (n % 10 == 7) return 1;
        n /= 10;
    }
    return 0;
}

그런데, for 루프와 대입문을 사용하지 말자.. 라는 것은 재귀호출을 이용하라는 의미같아요.

pingpong은 재귀함수를 하나 뽑아내서..

int pingpong_(int n, int i, int step, int value) {
    if (i<=n) {
        return pingpong_(n, i+1, (i % 7 == 0 || contains7(i)) ? -step : step, value + step);
    } else {
        return value;
    }
}

int pingpong(int n) {
    return pingpong_(n, 1, 1, 0);
}

contains7도 재귀로 바꿀 수 있겠네요.

int contains7(int n) {
    if (n % 10 == 7) return 1;
    if (n == 0) return 0;
    return contains7(n / 10);
}

2016/11/04 16:23

Han Jooyung

def pingpong(x):
    if x == 1 or x == 2:
        return pingPongList[x-1]

    elif x%7 == 1 or '7' in str(x-1):

        if pingPongList[x-3] < pingPongList[x-2]:
            pingPongList.append(pingPongList[x-2] - 1)
            return pingPongList[x-1]

        else:
            pingPongList.append(pingPongList[x-2] + 1)
            return pingPongList[x-1]

    else:
        if x<=0 or int(x)!=x:
            pass

        elif pingPongList[x-3] < pingPongList[x-2]:
            pingPongList.append(pingPongList[x-2]+1)
            return pingPongList[x-1]

        else:
            pingPongList.append(pingPongList[x-2]-1)
            return pingPongList[x-1]

while True:
    pingPongList = [1, 2]
    num = int(input('개수를 입력하십시오: '))
    for i in range(1, num+1):
        print('단계:%s       핑퐁숫자: %s'%(i, pingpong(i)))

2016/11/25 23:11

fdn

public class test {
    public static void main(String[] args) {

        Scanner scan = new Scanner(System.in);
        int number = scan.nextInt();

        System.out.println("pingpong(" + number + ") = "+ pingpong(number));
    }

    public static int pingpong(int end) {

        int result = 0;         // return 결과값
        boolean flag = true;    // +,- 분기
                                // true 일 경우 + 
                                // false 일경우 -

        for(int i = 1 ; i <= end ; i ++) {          // end 값만큼 반복
            result = flag? result+1 : result-1;     // flag에 따른 result 값 + or -

            boolean flag1 = (i % 7 == 0);           // 7의 배수
            boolean flag2 = (i + "").contains("7"); // 7 포함 유무

            if(flag1 || flag2) {
                flag = flag?false:true;             // 위 조건 충족시 반대값 대입
            } 
        }

        return result;      // 결과 return
    } // pingpong end
}

심화는 확실히 어렵네요.. 오늘도 부족함만 잔뜩 느끼고 가는중... 아래는 아직 많이 부족한 심화 코드요 ㅠㅠ

public class test {

    public static void main(String[] args) {
        Scanner scan = new Scanner(System.in);
        int end = scan.nextInt();                   // 종료값 입력
        end = end < 1 ? 1 : end == 0 ? 1 : end;     // 종료값 음수, 0 방지

        System.out.println("pingpong(" +end + ") = " + pingpong(end));
    }

    public static int pingpong(int end) {
        return pingpong(0,1,end,true);              // 시작값, 회차, 종료값, + or -에 대한 flag
    }

    public static int pingpong(int num, int count, int end, boolean flag) {
        num = flag ? num + 1 : num - 1;
        flag = (includeSeven(count) || count % 7 == 0) ? (flag ? false : true ) : flag;
        return count == end ? num : pingpong(num, count+1, end, flag);
    }

    public static boolean includeSeven(int count) {
        return count % 10 == 7 ? true : (count > 9) ? includeSeven(count/10) : false ;
    }
}

2016/12/19 11:18

test

def check (x, y):
    if x % 7 == 0 or '7' in str(x): return y * (-1)
    else: return y

def findsol (target, count, answer, op):
    if count == target: print(answer);
    else: findsol(target, count + 1, answer + check(count, op), check(count,op))

def pingpong(x): return findsol(x,1,1,1)

2017/01/26 19:04

SJ

파이썬 2.7으로 작성하였습니다.

def sevenCount(num):
    if num == 0 : return 0
    elif '7' in str(num) or num % 7 == 0:   return 1+sevenCount(num-1)
    else :  return sevenCount(num-1)

def pingpong(num):
    if num == 0:    return 0
    else :  return pingpong(num-1)+pow(-1,sevenCount(num-1))

print pingpong(22)

2017/02/24 17:36

Chop

MATLAB 입니다.
if 조건문의 향연이네요 ㅜㅠ

pingpong(8)
pingpong(22)
pingpong(68)
pingpong(100)

6
0
2
2
나옵니다

function [nth_number,p_m_sign]=pingpong(val)
    if val==1
        nth_number=1;
        p_m_sign=1;
    else
        [prev_nth_number,prev_p_m_sign]=pingpong(val-1);
        nth_number=prev_nth_number+prev_p_m_sign;
        if mod(val,7)==0 || has_7(val)==1
            p_m_sign=-1*prev_p_m_sign;
        else
            p_m_sign=prev_p_m_sign;
        end
    end
end

function result=has_7(val)
    if val<10
            if val==7
                result=1;
            else
                result=0;
            end
    elseif rem(val,10)==7
        result=1;
    else
        result=has_7(floor(val/10));
    end
end

2017/03/05 12:42

c0din9

/**
 * URL : http://codingdojang.com/scode/514
 * 각자리수를 찾는 방법을 재귀로 구현
 */
public class PingPong {

    public static void main(String[] args) {
        pingpong(68);
    }

    private static void pingpong(int n) {
        ping(1, 1, n, 1);
    }

    private static void ping(int i, int v, int n, int d) {
        if (i == n) {
            System.out.println(i + " " + v);
            return;
        }
        i = i + 1;
        v = v + d;
        boolean b = pong(i, 10);
        if (i % 7 == 0 || b) {
            d = d * -1;
        }
        ping(i, v, n, d);
    }

    private static boolean pong(int i, int d) {
        if ((i / d) < 10) return false;
        if (i % d == 7) return true;
        return pong(i, 10 * d);
    }
}

2017/03/28 13:38

genius.choi

#include <iostream>

void Pingpong(int cnt);
using namespace std;

int main()
{
    int number;
    cin >> number;
    Pingpong(number);
    return 0;
}

void Pingpong(int cnt)
{
    bool is_include7 = false;
    int temp, data, sign;
    data = 0;
    sign = 1;

    for (int i = 0; i < cnt; i++)
    {
        data += sign;
        temp = i + 1;
        while (temp != 0) // n번째의 n이라는 숫자에 7이란 숫자가 포함되었는지?
        {
            if (temp % 10 == 7) {
                is_include7 = true;
                break;
            }
            temp /= 10;
        }

        if (((i + 1) % 7 == 0) || is_include7 == true)  //n번째의 n이라는 숫자가 7의 배수이거나 7을 포함하면?
            sign = -sign; //부호 변경
        is_include7 = false;
        cout << data << " ";
    }
    cout << endl;
    cout << "Result: " << data << endl;
}

2017/04/09 03:47

GyuHo Han

javascript

var direction = (c, d) => c % 7 === 0 || /7/.test(c) ? -d : d;
var pingpong = function(t, n = 0, c = 1, d = 1) {
    return c === t ? n + d : pingpong(t, n + d, c + 1, direction(c, d));
};

console.log(pingpong(8)); // = 6
console.log(pingpong(22)); // = 0
console.log(pingpong(68)); // = 2
console.log(pingpong(100)); // = 2

2017/06/26 12:05

funnystyle

object PingPong
{
  def IsInclude7(N: Int, sN: String): Int = if(((0 until sN.length) map(sN(_).toInt)).lastIndexOf(55) != -1) 1 else 0
  def IsDivided7(N: Int): Int = if(N % 7 == 0) 1 else 0
  def Interface7(N: Int): Int = IsInclude7(N,s"$N") + IsDivided7(N)
  def TnFToInt(B: Boolean): Int = if(B) 1 else -1
  def PingPongGo(N: Int, i: Int, Direction : Boolean, Finish: Int, PPSeq: IndexedSeq[Int]): IndexedSeq[Int] = {
    if(i < Finish)
      {
        if(Interface7(i) == 0)
          PingPongGo(N+TnFToInt(Direction),i+1,Direction,Finish, PPSeq:+N)
        else
          PingPongGo(N-TnFToInt(Direction),i+1,!Direction,Finish, PPSeq:+N)
      }
    else
      PPSeq:+N
  }
  def PingPongStart(Finish: Int): IndexedSeq[Int] = PingPongGo(1,1,true,Finish,IndexedSeq[Int]())
  def main(Args : Array[String]): Unit = print(PingPongStart(50))
}

심화는 아직 생각해봐야겠습니다..

2017/07/19 01:55

S ReolSt

def pingpong(n):
    x, d = 1, 1
    for i in range(2, n + 1):
        x += d
        if i % 7 == 0 or '7' in str(i):
            d = -d

    return x

for n in [8, 22, 68, 100]:
    print('pingpong(%d) = %d' % (n, pingpong(n)))

심화

def contain7(i):
    if i == 0:          return False
    elif i % 10 == 7:   return True
    else:               return contain7(i // 10)

def nextdir(d, i):
    return -d if (i % 7 == 0 or contain7(i)) else d

def pingpong(n, x=1, d=1, i=1):
    return x if i == n else pingpong(n, x + nextdir(d, i), nextdir(d, i), i + 1)

2017/08/19 01:34

Noname

def ping_pong(n) :
    result = []
    a = 1
    plus = 1
    for s in range(1, n + 1) :
        result.append(a)

        if str(s)[-1] == '7' or s % 7 == 0 :

            if plus == 1 :
                plus = -1
                a += plus

            else :
                plus = 1
                a += plus

        else :
            a += plus

    return result[-1]

2017/08/25 12:17

다크엔젤

def pingpong(x): if x==1: return 1 if x==2: return 2 direction=pingpong(x-1)-pingpong(x-2) if (x-1)%7==0 or (x-1)/10%7==0 or (x-1)/100%7==0: return pingpong(x-1)-direction return pingpong(x-1)+direction print(pingpong(8)) 세자리수까지

2017/08/26 21:38

impri

참 더러운 코드지만 용서해주세용..

#include<iostream>
using namespace std;

int pingpong(int _num)
{
    int num[100];
    bool sw = false;
    int countNum = 1;

    for (int i = 0; i < 100; i++)
    {
        if (!sw)
        {
            num[i] = countNum;

            if ((i + 1) % 7 == 0 || (i + 1) % 10 == 7 || ((i + 1) % 100) / 10 == 7 ) //7의 배수 이거나 첫째 자리수가 7이면
                sw = true;
            else
                countNum++;
        }
        else
        {
            num[i] = countNum - 1;
            if ((i + 1) % 7 == 0 || (i + 1) % 10 == 7 || ((i + 1) % 100) / 10 == 7)
                sw = false;
            else
                countNum--;
        }
    }
    return num[_num - 1];
}
int main()
{
    cout << pingpong(8) << endl;
    cout << pingpong(22) << endl;
    cout << pingpong(68) << endl;
    cout << pingpong(100) << endl;

}

2017/12/10 21:08

와디더

Haskell

  • 나눗셈이나 문자열 연산을 사용하지 않고, 수열의 꼭짓점들을 직접 구합니다.
  • 꼭짓점의 차를 교대로 더하고 빼서 pingpong n을 구합니다.
  • 그렇기 때문에 sum(getSignUsingDivision for [1..n])와 같이 구하는 것보다 훨씬 빠를줄 알았는데 생각만큼 드라마틱하지는 않네요. 제 가상머신에서 아래 naive 버전은 1160ms, 이 버전은 995ms정도 소모합니다.
import Control.Applicative

merge :: (Eq a, Ord a) => [a] -> [a] -> [a]
merge xs [] = xs
merge [] ys = ys
merge (x:xs) (y:ys)
    | x >  y = y : merge (x:xs) ys
    | x <  y = x : merge xs (y:ys)
    | x == y = x : merge xs ys


pingpong :: Int -> Int -- fmap pingpong [1..] == [1, 2, 3, 4, 5, 6, 7, 6, 5, ...]
pingpong n = sum $ zipWith (*) (cycle [1,-1]) $ zipWith (-) =<< tail $ takeWhile (< n) extrema ++ [n]

extrema :: [Int] -- extrema == [0, 7, 14, 17, 21, 27, 28, ...]
extrema = merge [0, 7..] $ [0..] >>= \n -> foldr1 merge $ fmap (sevens n) [0..n]
    where
        sevens m n
            | m == n    = liftA2 (+) [7*10^n] [0..10^n-1]
            | otherwise = liftA2 (+) [10^m + 7*10^n, 10^m + 17*10^n..10^(m+1)] [0..10^n-1]

main = print $ pingpong 10000000

naive

import Control.Applicative
pingpong' :: Int -> Int
pingpong' n = sum $ scanl acc 1 [1..n-1]

acc s n = if liftA2 (||) cond1 cond2 n then -s else s
cond1 = (==0) . (`rem` 7)
cond2 = any (==7) . fmap (`rem` 10) . takeWhile (/= 0) . iterate (`div` 10)

main = print $ pingpong' 10000000

2017/12/25 04:59

sodii

자바요

public static void main(String[] args)
    {
        main ma = new main();
        System.out.println(ma.pingpong(100));
    }

    public int pingpong(int num)
    {
        return recursiveFunc(num, 1, 1, 0);
    }

    public int recursiveFunc(int end, int cur, int cnt, int updown)
    {
        if(cnt == end)
        {
            return cur;
        }
        else
        {
            if(cnt % 7 == 0 || cnt % 10 == 7 || cnt / 10 == 7)
            {
                if(updown == 0)
                {
                    return recursiveFunc(end, cur-1, cnt+1, 1); 
                }
                else
                {
                    return recursiveFunc(end, cur+1, cnt+1, 0);
                }
            }
            else
            {
                if(updown == 0)
                {
                    return recursiveFunc(end, cur+1, cnt+1, 0); 
                }
                else
                {
                    return recursiveFunc(end, cur-1, cnt+1, 1);
                }
            }
        }
    }

2018/01/11 12:57

강승규

파이썬 3.6

def check_7(n):
    if n%10 == 7:
        return True
    elif n//10 == 7:
        return True
    elif n%10 != 7 and n//10 != 7 and (n//10)//10 == 0:
        return False
    else:
        n = n//10
        if check_7(n):
            return True
        else:
            return False

def pingpong(n):
    t,num,direction = 1,0,1
    while t <= n:
        if t % 7 == 0 or check_7(t):
            if direction == 1:
                num += 1
                direction -= 1
            else:
                num -= 1
                direction += 1
        else:
            if direction == 1:
                num += 1
            else:
                num -= 1
        t += 1
    print("pingpoing(%d) =  %d"%(t-1,num))

if __name__ == "__main__":
#    n = int(input(''))
    pingpong(8)
    pingpong(22)
    pingpong(68)
    pingpong(100)
    pingpong(1000000)
  • 결과값
pingpoing(8) =  6
pingpoing(22) =  0
pingpoing(68) =  2
pingpoing(100) =  2
pingpoing(1000000) =  -868

2018/02/12 20:24

justbegin

n = 1000000인 경우 2초 내로 나옵니다.

def check7(n):
    if n%7 == 0:
        return True
    else:
        while 1:
            if n%10 ==7:
                return True
            if n//10 == 0:
                break
            n = n//10
        return False
def pingpong(n):
    increase = 1
    i = 1
    num = 1
    while i < n:
        i += 1
        num += increase
        if check7(i):
            increase = increase*(-1)
    return num

2018/02/22 11:34

김동하

def pingpong(n):
    m=1
    ad=1
    for i in range(1,n):
        if 0==(1-('7' in str(i)))* (1-(i%7==0)):
            ad= ad*(-1) 
        m+=ad
    return m

2018/03/12 16:53

김자현

#include <stdio.h>
int main() {
    int input, re=1, ad=1, mu, temp;


    printf("숫자를 입력하시오.\n");
    scanf_s("%d", &input);

    for (int i = 1; i < input; i++) {
        mu = i%7;
        temp = i;
        while (temp > 0) {
            mu *= 1-((temp % 10) == 7);
            temp = temp / 10;
        }
        if (mu == 0){
            ad = ad * (-1);
        }
        re += ad;
    }
    printf("%d", re);
    return 0;
}

2018/03/12 19:30

탁성하

def pingpong(x):
    a=1
    b=0
    for i in range(1,x+1):
        b=b+(1*a)
        if i%7==0 or '7' in str(i) : a=a*(-1)
    return b

2018/03/13 20:51

코끼리식당

    public static void main(String[] args) throws Exception {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        int t = Integer.parseInt(br.readLine()); 

        int cnt = 0;
        int ping = 0;
        boolean seven = false;
        for (int i=0; i<t; i++) {
            cnt++;
            ping = seven ? ping-1 : ping+1;
            if(String.valueOf(cnt).contains("7") || cnt % 7 == 0) 
                seven = !seven;
        }
        System.out.println(ping);
    } // 스트링을 안쓰고 cnt가 7을 포함하느냐 구별하는 건 정규식을 사용해야 될 거 같은데 일단은 여기까지 했습니다... 심화과정은 다음에 해야지

2018/05/04 09:26

정몽준

Swift입니다.

Loop, Assignment, String없이 풀었습니다. 위 조건을 맞추려니, 재귀호출뿐이 없네요.

func contains7(_ number: Int) -> Bool {
    return number % 10 == 7 ? true : (number / 10 < 1 ? false : contains7(number / 10))
}

func pingpong(_ target: Int, _ direction: Int = 1, _ number: Int = 0, _ count: Int = 0) -> Int {
    if count == target {
        return number
    }
    if (count + 1) % 7 == 0 || contains7(count + 1) {
        return pingpong(target, direction * -1, number + direction, count + 1) 
    }
    return pingpong(target, direction, number + direction, count + 1)
}

print( pingpong(8) )
print( pingpong(22) )
print( pingpong(68) )
print( pingpong(100) )
print( pingpong(1000) )

결과는...

6
0
2
2
-26

2018/05/11 06:50

졸린하마

순서대로 진행해 나가면서 direction으로 방향만 전환하며 더해주는 방법으로 풀었습니다. 7을 포함하는지 확인 작업과 순서대로 진행하는 것을 재귀를 사용했기 때문에 문자열이나, 변수 할당을 사용할 필요가 없습니다.

    def pingPong(N:Int):Int ={
      def has_seven(num:Int):Boolean = {
        num match {
          case 0 => false
          case x if num % 10 == 7 => true
          case _ => has_seven(num / 10)
        }
      }
      def step(n:Int, direction:Int, ans:Int):Int = {
        n match {
          case x if n == N =>  ans
          case x if n % 7 == 0 || has_seven(n) => step(n + 1, -1*direction, ans + -1*direction)
          case _ => step(n + 1, direction, ans + direction)
        }
      }
      step(1, 1 , 1)
    }
    println(pingPong(8))
    println(pingPong(22))
    println(pingPong(68))
    println(pingPong(100))

2018/05/22 18:56

한강희

  • 심화 조건(x)
public class PingPong {
    public static void main(String[] args) {
        pingpong(100);
    }

    private static void pingpong(int Q) {
        int num = 0;
        int sw = 1;
        int count = 0;
        while (Q != count++) {
            num += sw;
            if (count % 7 == 0 || (count + "").contains("7"))
                sw *= -1;
        }
        System.out.println(num);
    }
}

  • String(x)

public class PingPong {
    public static void main(String[] args) {
        pingpong(8);
        pingpong(22);
        pingpong(68);
        pingpong(100);
    }

    private static void pingpong(int Q) {
        int num = 0;
        int sw = 1;
        int count = 0;
        while (Q != count++) {
            num += sw;
            if (count % 7 == 0 || Check(count))
                sw *= -1;
        }
        System.out.println(num);
    }

    private static boolean Check(int num) {
        return (num % 10 == 7 || (num > 0 && Check(num / 10)) ? true : false);
    }
}
  • String(x), For(x)

public class PingPong {
    public static void main(String[] args) {
        pingpong(8);
        pingpong(22);
        pingpong(68);
        pingpong(100);
    }

    private static void pingpong(int Q) {
        Cal(0, 0, -1, Q);
    }

    private static int Cal(int num, int count, int sw, int Q) {
        if (count % 7 == 0 || Check(count)) 
            sw *= -1;
        num += sw;
        if (Q == 1) {
            System.out.println(num);
            return num;
        }
        Cal(num, ++count, sw, --Q);
        return num;
    }

    private static boolean Check(int num) {
        return (num % 10 == 7 || (num > 0 && Check(num / 10)) ? true : false);
    }
}

2018/06/01 17:11

김지훈

def pingpong1(a):
     ping,pm = [1],1
     while a != len(ping):
          ping.append(ping[-1] + pm)
          if len(ping) % 7 == 0 or str(len(ping)) in '7':
               pm *= -1
     print(ping[-1])

2018/06/25 20:34

김영성

def pingpong(x):
    p,r = 0,0
    for i in range(1,x+1):
        r = r + (-1)**p
        if i%7 == 0 or '7' in str(i): p = (1,0)[p]
    return r

2018/07/26 18:46

Creator



def pingpong(_input):

    if _input<8:
        return _input
    t=[i for i in range(1,_input+1) if (i%7 ==0) or ('7' in str(i))]
    a=[t[i]-t[i-1] for i in range(1,len(t))]
    c=list(map(lambda x: x[1] if x[0]%2==1 else -x[1], enumerate(a)))
    return 7+sum(c)+t[-1]-_input if len(t)%2==1 else 7+sum(c)-t[-1]+_input


2018/12/15 12:02

최용선

def includeSeven(n): #숫자에 7이 포함돼있는지 확인하는 함수
  while n != 0:
    if n%10 == 7: return True
    n = n//10
  #n이 세자리수 이하일 때는 아래와 같이 변수할당없이 표현가능
  #if n%10==7 or (n//10)%10==7 or (n//100)%10: return True
  return False

def f(n, sign, k, _max): #재귀함수
  if k >= _max:
    return n
  if k%7 == 0 or includeSeven(k):
    return f(n + (-1)*sign, (-1)*sign, k+1, _max)    
  return f(n + sign, sign, k+1, _max)

def pingpong(n):
  return f(1, 1, 1, n)
>>> pingpong(8)
6
>>> pingpong(22)
0
>>> pingpong(68)
2
>>> pingpong(100)
2

2019/04/23 13:13

messi

def seven(s) :
    if s % 7 == 0 :
        return True
    if s % 10 == 7 :
        return True
    if 80 > s % 100 > 69 :
        return True
    if 800 > s % 1000 > 699 :
        return True
    return False

# k, i,  n, o는 각각 초기치, 스텝, 초기 항 번호, 목표 항 번호
def ping(k, i, n, o) :
    if n == o :
        return k
    elif seven(n) == True :
        return ping(k-i, -i, n+1, o)
    elif seven(n) == False :
        return ping(k+i, i, n+1, o)

def pingpong(p) :
    return ping(1, 1, 1, p)

print(pingpong(8))
print(pingpong(22))
print(pingpong(68))
print(pingpong(100))

재귀함수를 익히는데 아주 좋은 기회가 됐습니다.

결과

6
0
2
2

2019/12/12 16:13

GG

#파이썬

#처음에 쉽게 문제를 풀었다가 제약조건이 있는걸 보고
#배열도 없애고 String도 없앴습니다
#변수 할당을 하지 말것은 변수 자체를 쓰지 마라는 의미인가요? 
#변수를 안쓰고는 도저히 어떻게 해야할지 모르겠습니다 ㅜㅜㅜ

def pingpong(x):
    p,pp,sign=0,0,1 
    while (pp<x):
        p+=sign
        pp+=1
        if pp%7==0 or pp%10==7 or pp//10==7 or pp//100==7:
            sign*=-1       
    print ('pingping(',x,')=',p)

pingpong(8)
pingpong(22)
pingpong(68)
pingpong(100)

2020/05/15 09:42

Buckshot

pingping( 8 )= 6 pingping( 22 )= 0 pingping( 68 )= 2 pingping( 100 )= 2 - Buckshot, 2020/05/15 09:43
def pingpong(a):
    count=0
    b=0
    i=0
    c=[]
    while i<=a:
        while True:
            i+=1
            count+=1
            b+=1
            c.append(b)
            if count%7==0 or '7' in str(count) :
                break
        while True:
            i+=1
            count+=1
            b-=1
            c.append(b)
            if count%7==0 or '7' in str(count) :
                break
    print(c[a-1])

pingpong(100)

조건은 못지키겠네요..

2021/03/30 22:37

fox.j

def has7(n):
    return n % 7 == 0 or '7' in str(n)

def pingpong(limit, val=1, direction=1, count=1):
    if count == limit:
        return val
    if has7(count):
        direction *= -1
    return pingpong(limit, val+direction, direction, count+1)

for n in [8,22,68,100]:
    print('pingpong(',n,') = ', pingpong(n))

2023/11/01 20:15

insperChoi

목록으로