코딩 테스트/Level 2
10. 타겟 넘버
컴닥
2020. 7. 24. 16:43
반응형
https://programmers.co.kr/learn/courses/30/lessons/43165
파이썬
def solution(numbers, target):
answer = 0
for checker in range((1 << len(numbers)) - 1, -1, -1):
total = 0
for i in range(len(numbers) - 1, -1, -1):
divisor = 1 << i
if checker // divisor == 1:
total += numbers[len(numbers) - i - 1]
else:
total -= numbers[len(numbers) - i - 1]
checker %= divisor
if total == target:
answer += 1
return answer
'''
테스트 1 〉 통과 (4560.46ms, 10.7MB)
테스트 2 〉 통과 (4567.11ms, 10.7MB)
테스트 3 〉 통과 (2.30ms, 10.7MB)
테스트 4 〉 통과 (11.32ms, 10.9MB)
테스트 5 〉 통과 (109.21ms, 10.7MB)
테스트 6 〉 통과 (5.24ms, 10.8MB)
테스트 7 〉 통과 (2.48ms, 10.8MB)
테스트 8 〉 통과 (23.77ms, 10.9MB)
'''
특이하게 풀어보고 싶어서 비트 연산자를 사용했습니다.
numbers의 개수가 3인 경우 이진수 111, 110, 101, 100, 011, 010, 001, 000를
이용해서 1 또는 0이 나온 자리의 원소를 + 또는 - 하면서 조합을 만드는 방식입니다.
재귀를 이용하는 방식보단 많이 늦군요.. ㅜㅜ 코테에 속도가 중요하지 않지 말입니다. https://namu.wiki/w/IOCCC
자바스크립트
function solution(numbers, target) {
let answer = 0;
for (let i = (1 << numbers.length) - 1; i >= 0; i--) {
let total = 0
let checker = i
for (let j = numbers.length - 1; j >= 0; j--) {
let divisor = 1 << j;
if (parseInt(checker / divisor) == 1)
total += numbers[numbers.length - j - 1]
else
total -= numbers[numbers.length - j - 1]
checker %= divisor
}
if (total == target) answer++
}
return answer;
}
/*
테스트 1 〉 통과 (427.75ms, 43.7MB)
테스트 2 〉 통과 (430.29ms, 43.6MB)
테스트 3 〉 통과 (4.07ms, 37.6MB)
테스트 4 〉 통과 (5.21ms, 38.1MB)
테스트 5 〉 통과 (16.37ms, 42.1MB)
테스트 6 〉 통과 (4.78ms, 37.8MB)
테스트 7 〉 통과 (3.99ms, 37.7MB)
테스트 8 〉 통과 (7.90ms, 39.1MB)
*/
당연한 이야기지만 파이썬의 for문이 좀 특이 합니다.
다른 언어들의 for 문에서는 for 문 안에서 index에 변형을 주면 꼬여 버리는데..
(변형된 것에 -- ++ 등을 해주면서 안드로메다로 휘리릭...)
파이썬의 for 문은 뒤에 range 함수에서 숫자를 하나씩 꺼내는 개념이라서
(정확하겐 구글에서 iterable range python을 검색해보시길..)
for 문 내에서 index에 장난을 쳐도.. for 문을 만나면 정상적(?)으로 다음 숫자가 튀어나옵니다..
(기본적으로 foreach 개념이니까...)
사실 저 위의 파이썬 예제에서는 한 줄을 줄이기 위해 checker를 그렇게 돌려막기를 합니다.
사실 좋은 코딩은 아니죠. 다른 언어 사용하는 사람에게도 직관적으로 이해할 수 있도록 어느 정도는 맞춰줘야 ...하지만 코드 뽐내기는 한줄을 줄이기 위해.. 최대한 응용, 노오력...
Java
class Solution {
public int solution(int[] numbers, int target) {
var answer = 0;
for (var i = (1 << numbers.length) - 1; i >= 0; i--) {
var total = 0;
var checker = i;
for (var j = numbers.length - 1; j >= 0; j--) {
var divisor = 1 << j;
if (checker / divisor == 1)
total += numbers[numbers.length - j - 1];
else
total -= numbers[numbers.length - j - 1];
checker %= divisor;
}
if (total == target) answer++;
}
return answer;
}
}
/*
테스트 1 〉 통과 (233.63ms, 50.3MB)
테스트 2 〉 통과 (233.43ms, 52.7MB)
테스트 3 〉 통과 (1.32ms, 52.2MB)
테스트 4 〉 통과 (2.80ms, 53.1MB)
테스트 5 〉 통과 (12.24ms, 52.7MB)
테스트 6 〉 통과 (2.17ms, 50.1MB)
테스트 7 〉 통과 (1.29ms, 52.1MB)
테스트 8 〉 통과 (4.35ms, 50.3MB)
*/
Kotlin
class Solution {
fun solution(numbers: IntArray, target: Int): Int {
var answer = 0
for (i in (1 shl numbers.size) - 1 downTo 0) {
var total = 0
var checker: Int = i
for (j in numbers.indices.reversed()) {
val divisor = 1 shl j
if (checker / divisor == 1) {
total += numbers[numbers.size - j - 1]
} else {
total -= numbers[numbers.size - j - 1]
}
checker %= divisor
}
if (total == target) answer++
}
return answer
}
}
/*
테스트 1 〉 통과 (238.08ms, 59.5MB)
테스트 2 〉 통과 (222.73ms, 57.3MB)
테스트 3 〉 통과 (3.60ms, 59.2MB)
테스트 4 〉 통과 (5.45ms, 59.3MB)
테스트 5 〉 통과 (13.48ms, 57.2MB)
테스트 6 〉 통과 (3.43ms, 59MB)
테스트 7 〉 통과 (2.85ms, 57.3MB)
테스트 8 〉 통과 (8.53ms, 57.5MB)
*/
코틀린의 비트연산자는 신기합니다.
C#
public class Solution
{
public int solution(int[] numbers, int target)
{
var answer = 0;
for (var i = (1 << numbers.Length) - 1; i >= 0; i--)
{
var total = 0;
var checker = i;
for (var j = numbers.Length - 1; j >= 0; j--)
{
var divisor = 1 << j;
if (checker / divisor == 1)
total += numbers[numbers.Length - j - 1];
else
total -= numbers[numbers.Length - j - 1];
checker %= divisor;
}
if (total == target) answer++;
}
return answer;
}
}
/*
테스트 1 〉 통과 (255.49ms, 56.9MB)
테스트 2 〉 통과 (255.31ms, 54.9MB)
테스트 3 〉 통과 (12.15ms, 54.6MB)
테스트 4 〉 통과 (13.78ms, 59MB)
테스트 5 〉 통과 (19.22ms, 58.7MB)
테스트 6 〉 통과 (13.25ms, 56.8MB)
테스트 7 〉 통과 (12.07ms, 54.3MB)
테스트 8 〉 통과 (14.03ms, 58.4MB)
*/
GO
func solution(numbers []int, target int) (answer int) {
for j := (1 << uint(len(numbers))) - 1; j >= 0; j-- {
total := 0
for check, i := j, len(numbers)-1; i >= 0; i-- {
divisor := 1 << uint(i)
if int(check/divisor) == 1 {
total += numbers[i]
} else {
total -= numbers[i]
}
check %= divisor
}
if total == target {
answer++
}
}
return
}
/*
테스트 1 〉 통과 (293.23ms, 9.12MB)
테스트 2 〉 통과 (293.23ms, 9.09MB)
테스트 3 〉 통과 (0.23ms, 9.19MB)
테스트 4 〉 통과 (0.84ms, 9.13MB)
테스트 5 〉 통과 (6.94ms, 7.18MB)
테스트 6 〉 통과 (0.42ms, 9.2MB)
테스트 7 〉 통과 (0.19ms, 9.52MB)
테스트 8 〉 통과 (1.76ms, 11.1MB)
*/
반응형