.foregroundColor(UIColor.systemBlue)
// Cannot convert value of type 'UIColor' to expected argument type 'Color?'
그냥 Color() 생성자를 쓰면 바로 바꿔진다
.foregroundColor(Color(UIColor.systemBlue))
도대체 왜 그냥 자동고침으로 변경이 안되는걸까?...
참고로 저 Color의 생성자는 아래와같이 선언되어있다.
extension Color {
/// Creates a color from a UIKit color.
///
/// Use this method to create a SwiftUI color from a
/// <doc://com.apple.documentation/documentation/UIKit/UIColor> instance.
/// The new color preserves the adaptability of the original.
/// For example, you can create a rectangle using
/// <doc://com.apple.documentation/documentation/UIKit/UIColor/3173132-link>
/// to see how the shade adjusts to match the user's system settings:
///
/// struct Box: View {
/// var body: some View {
/// Color(UIColor.link)
/// .frame(width: 200, height: 100)
/// }
/// }
///
/// The `Box` view defined above automatically changes its
/// appearance when the user turns on Dark Mode. With the light and dark
/// appearances placed side by side, you can see the subtle difference
/// in shades:
///
/// 
///
/// > Note: Use this initializer only if you need to convert an existing
/// <doc://com.apple.documentation/documentation/UIKit/UIColor> to a
/// SwiftUI color. Otherwise, create a SwiftUI ``Color`` using an
/// initializer like ``init(_:red:green:blue:opacity:)``, or use a system
/// color like ``ShapeStyle/blue``.
///
/// - Parameter color: A
/// <doc://com.apple.documentation/documentation/UIKit/UIColor> instance
/// from which to create a color.
public init(_ color: UIColor)
}
func remoteCommandCenterSetting() {
// remote control event 받기 시작
UIApplication.shared.beginReceivingRemoteControlEvents()
let center = MPRemoteCommandCenter.shared()
center.playCommand.removeTarget(nil)
center.pauseCommand.removeTarget(nil)
// 제어 센터 재생버튼 누르면 발생할 이벤트를 정의합니다.
center.playCommand.addTarget { (commandEvent) -> MPRemoteCommandHandlerStatus in
self.avPlayer.play()
MPNowPlayingInfoCenter.default()
.nowPlayingInfo?[MPNowPlayingInfoPropertyElapsedPlaybackTime] = NSNumber(value: self.avPlayer.currentTime)
// 재생 할 땐 now playing item의 rate를 1로 설정하여 시간이 흐르도록 합니다.
MPNowPlayingInfoCenter.default().nowPlayingInfo?[MPNowPlayingInfoPropertyPlaybackRate] = 1
return .success
}
// 제어 센터 pause 버튼 누르면 발생할 이벤트를 정의합니다.
center.pauseCommand.addTarget { (commandEvent) -> MPRemoteCommandHandlerStatus in
self.avPlayer.pause()
MPNowPlayingInfoCenter.default().nowPlayingInfo?[MPNowPlayingInfoPropertyElapsedPlaybackTime] = NSNumber(value: self.avPlayer.currentTime)
// 일시정지 할 땐 now playing item의 rate를 0으로 설정하여 시간이 흐르지 않도록 합니다.
MPNowPlayingInfoCenter.default().nowPlayingInfo?[MPNowPlayingInfoPropertyPlaybackRate] = 0
return .success
}
center.nextTrackCommand.addTarget { event in
let nextResult = self.nextAction()
if !nextResult {
return .noSuchContent
}
return .success
}
center.previousTrackCommand.addTarget { event in
_ = self.previousAction()
return .success
}
center.playCommand.isEnabled = true
center.pauseCommand.isEnabled = true
}
func remoteCommandInfoCenterSetting() {
let center = MPNowPlayingInfoCenter.default()
var nowPlayingInfo = center.nowPlayingInfo ?? [String: Any]()
guard let currentMusic: MusicInfo = playList.currentMusic else {
print("리스트에 곡이 없음")
return
}
nowPlayingInfo[MPMediaItemPropertyTitle] = currentMusic.title
nowPlayingInfo[MPMediaItemPropertyArtist] = currentMusic.artist
if let albumCoverPage = currentMusic.artworkImage {
nowPlayingInfo[MPMediaItemPropertyArtwork] = MPMediaItemArtwork(boundsSize: albumCoverPage.size, requestHandler: { size in
return albumCoverPage
})
}
// 콘텐츠 총 길이
nowPlayingInfo[MPMediaItemPropertyPlaybackDuration] = self.avPlayer.duration
// 콘텐츠 재생 시간에 따른 progressBar 초기화
nowPlayingInfo[MPNowPlayingInfoPropertyPlaybackRate] = 1
// 콘텐츠 현재 재생시간
nowPlayingInfo[MPNowPlayingInfoPropertyElapsedPlaybackTime] = NSNumber(value: self.avPlayer.currentTime)
center.nowPlayingInfo = nowPlayingInfo
}
var newPicture: [String] = []
for i in 0 ..< picture.count {
for _ in 0 ..< k {
newPicture.append(picture[i])
}
}
for line in 0 ..< newPicture.count {
let arr = Array(newPicture[line])
var newLine: [String.Element] = []
for i in 0 ..< arr.count {
for _ in 0 ..< k {
newLine.append(arr[i])
}
}
newPicture[line] = newLine.map({ String($0) }).joined()
}
return newPicture
세로로 늘리고 가로로늘리고를 크게 두가지로 나눠서 처리했는데 이걸 한번에 묶어서 처리를 하는게 인기가 좋나보다.... 다른답들 다 그렇게 처리가 되어있다
2. 정수를 나선형으로 배치하기
이중배열을 시계방향으로 돌아가면서 방문하는 문제이다.
class Position {
var x: Int
var y: Int
init(x: Int, y: Int) {
self.x = x
self.y = y
}
init(_ copy: Position) {
self.x = copy.x
self.y = copy.y
}
}
enum Direction {
case right, left, down, up
}
func solution(_ n:Int) -> [[Int]] {
var map: [[Int]] = Array(repeating: Array(repeating: 0, count: n), count: n)
// 캐릭터 현재 x,y 좌표
let position: Position = .init(x: 0, y: 0)
var checkNumber: Int = 1
func isMoveRight() -> Bool {
let startX = position.x
let startY = position.y
let nextX = startX + 1
// 맵 범위밖
if nextX >= n {
return false
}
// 이미 탐사한 지역
if map[startY][nextX] > 0 {
return false
}
return true
}
func isMoveLeft() -> Bool {
let startX = position.x
let startY = position.y
let nextX = startX - 1
if nextX < 0 {
return false
}
if map[startY][nextX] > 0 {
return false
}
return true
}
func isMoveDown() -> Bool {
let startX = position.x
let startY = position.y
let nextY = startY + 1
if nextY >= n {
return false
}
if map[nextY][startX] > 0 {
return false
}
return true
}
func isMoveUp() -> Bool {
let startX = position.x
let startY = position.y
let nextY = startY - 1
if nextY < 0 {
return false
}
if map[nextY][startX] > 0 {
return false
}
return true
}
func checkMap(position: Position) -> Bool {
if map[position.y][position.x] > 0 {
print("ERROR!!!!!")
return false
}
map[position.y][position.x] = checkNumber
checkNumber += 1
return true
}
// 시작 위치
_ = checkMap(position: position)
// 순서 right down left up
var direction: Direction = .right
while true {
let beforPosition: Position = .init(position)
// 이동 가능 체크
if !(isMoveRight() || isMoveLeft() || isMoveUp() || isMoveDown()) {
break
}
// 이동
switch direction {
case .right:
if isMoveRight() {
position.x += 1
} else {
direction = .down
}
case .down:
if isMoveDown() {
position.y += 1
} else {
direction = .left
}
case .left:
if isMoveLeft() {
position.x -= 1
} else {
direction = .up
}
case .up:
if isMoveUp() {
position.y -= 1
} else {
direction = .right
}
}
if beforPosition.x == position.x && beforPosition.y == position.y {
continue
}
// 맵 수정
_ = checkMap(position: position)
}
return map
}
이동하는걸 각 기능으로 나눠서 방향지정까지 해놨는데
솔직히 너무 과했다 쓸모없다
이렇게 해두면 그야 탐색 순서가 달라져도 써먹을 부분이 많겠지만 너무 오버했다
게임을 구현한다고 생각하니 뭔가 필받아서 머리가 나빠졌나보다
중간에 이동가능체크 라고 넣어둔부분은
추가로 루프 탈출지점을 깜빡해서 나중에 넣은 부분이라 저런다만 저런건 미리 계산해두고 사용하는게 좋을듯하다
아니 아예 인덱스부분만 골라서 숫자 올리는게 더 코드가 짧을지도 모르겠다
3. 정사각형으로 만들기
이중배열을 n형태의 배열로 만드는 문제, 줄수든 줄내의 요소수든 가장 큰값을 기준으로 0을 채워야한다
var maxECount: Int = 0
for e in arr {
maxECount = max(maxECount, e.count)
}
let targetCount: Int = max(arr.count, maxECount)
var resultArr: [[Int]] = Array(repeating: Array(repeating: 0, count: targetCount), count: targetCount)
for line in 0 ..< resultArr.count {
if line >= arr.count {
continue
}
for i in 0 ..< resultArr[line].count {
if i >= arr[line].count {
continue
}
resultArr[line][i] = arr[line][i]
}
}
return resultArr
이번에도 그냥 문제 내용대로
가장 큰수를 구하고 해당 큰수대로 정사각형 배열을 만들어줬다
문제는 기존 배열을 늘리는거지만 새롭게 만들어준거에 복사해주는것으로 대체.
그렇게 기초 트레이닝 문제가 끝!
마지막일자꺼는 왜 5문제가 아닐까....
24일날 시작하여 대부분은 25일까지 완료를 짖고 흥미가 떨어져 도전과제로 풀리는것만 풀다보니
일자로만 11일이 걸렸다.
하루에 day가 두개씩 열리는거보면 사이트에서 노린 기초 트레이닝 일자는 대략 14일 정도 2주가 아니였을까?
"사이트의 노림수대로 일자가 끝난거야 " 라며 자신을 위로하며 기초트레이닝 문제를 마무리한다.
한 이틀 정도만 꽤나 열심히 진행했고 그후로는 그냥 한두문제씩 풀고있는데 끝이보이는것도 신기하다
1. 전국대회선발고사
모든 사람의 등수와 이 사람들의 참가 가능여부를 담은 배열 두개를 넣어 마지막 계산식을 반환하는문제
var trueIndex: [Int] = []
for( i,b) in attendance.enumerated() {
if !b { continue }
trueIndex.append(i)
}
var playerRanks: [Int] = []
for i in trueIndex {
playerRanks.append(rank[i])
}
playerRanks.sort()
let top3PlayerRanks = playerRanks[0..<3]
var top3PlayerIndex: [Int] = []
for tRank in top3PlayerRanks {
let index = rank.firstIndex { rank in
rank == tRank
}
guard index != nil else {
return -1
}
top3PlayerIndex.append(index!)
}
guard top3PlayerIndex.count == 3 else { return -2 }
let a = top3PlayerIndex[0], b = top3PlayerIndex[1], c = top3PlayerIndex[2]
return 10000 * a + 100 * b + c
문제를 읽으면서 순서대로 코드로 옴겼더니 코드가 엄청 길어졌다.
일단 답은 맞아서 타인의 답을 볼수 있게 되었는데 zip을 이용해 원본인덱스와 등수를 저장한후 정렬,필터할 생각은 못했구나
엄청 짧게 가능한거 보면 대단들하다
2. 두 수의 합
대학시절 1학년때 가산기 만들던거를 코드로 만들어봐라 하는 문제이다
/**
어떻게 할까.
그냥 더해버리면 Int최대값을 넘어버린다, uint로 하면되지 않을까 했지만 안되고, longlongint로 하면되지않나? uint64도 넘어버리나보다.
문자열을 잘라서 일부분씩 더하고 넘어가는 자리만 따로 구해서 더하는 방식으로 가야겠다.
0. 네자리수의 문자열을 int형으로 변환후 더하고 자리수가 넘어가는 수와 분리해 넘어가는수, 합쳐진 네자리숫자를 반환하는 함수를 만든다.
1. 문자열의 뒤 네자리씩 자른 배열로만든다
2. 0에서 만든 함수를 돌려서 계산
3. 각 자리수 위치에 맞게 정렬해서 반환
- 한자리로 만들어 테스트해볼까?
*/
// return "\(UInt64(a)! + UInt64(b)!)"
// return (오버, 더해진값)
enum cError: Error {
case outOverRange
}
// 한자리 덧셈
func add(over: Int, a: Int, b: Int) throws -> (Int, String) {
if a > 9 || b > 9 || over > 9 {
throw cError.outOverRange
}
let total: Int = over + a + b
if total < 10 {
return (0, String(total))
}
let totalArr = Array(String(total))
// let over: Int = .init(String(totalArr[..<(totalArr.count - 1)]))!
let befor = String(totalArr[..<(totalArr.count - 1)])
let over = Int(befor)!
return (over, String(totalArr.last!))
}
let aArr = Array(a).map({ String($0) }).reversed().map { $0 }
let bArr = Array(b).map({ String($0) }).reversed().map { $0 }
let maxIndex = max(aArr.count, bArr.count)
var over: Int = 0
var result: [String] = []
for i in 0 ..< maxIndex {
var aNum: Int = 0, bNum: Int = 0
if i < aArr.count {
let str = aArr[i]
aNum = Int(str)!
}
if i < bArr.count {
let str = bArr[i]
bNum = Int(str)!
}
guard let calc = try? add(over: over, a: aNum, b: bNum) else {
return "error"
}
over = calc.0
result.append(calc.1)
}
if over > 0 {
result.append("\(over)")
}
return result.reversed().joined()
만들다 보니 또 엄청길어졌다..........
또 "나는 4자리씩 끊어서 해야지" 라고 마음먹고 시작했으나 막상 1자리가 성공적으로 되니 귀찮아져서 포기
가산기를 만들다보니 디지털논리회로 강의때가 생각나 또 과거회상에 빠져 현재와의 비교되는 과거에 우울해졌다
그때는 이것저것 해보면서 재밌었는데 안타깝다
아무튼 그렇게 day25로 구성된 문제집이 day24,25 밖에 안남아서 내일로 끝이날거다
처음 시작할때 넉넉잡아 일주일정도면 끝나겠지 했던 기초문제가 2주나 걸려버린거 생각하면 누군가 나에게 프로젝트 일정은 너가 생각한거의 두배를 말하면된다라는게 다시금 떠오른다